Chris Dick
/
Gameduino_Bitmap_demo
Bitmap demo for the Gameduino
main.cpp@1:3637b078dd83, 2012-12-21 (annotated)
- Committer:
- TheChrisyd
- Date:
- Fri Dec 21 13:47:20 2012 +0000
- Revision:
- 1:3637b078dd83
- Parent:
- 0:abda4161bf6e
updated Gameduino library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
TheChrisyd | 0:abda4161bf6e | 1 | #include "mbed.h" |
TheChrisyd | 0:abda4161bf6e | 2 | #include "GD.h" |
TheChrisyd | 0:abda4161bf6e | 3 | #include "shield.h" |
TheChrisyd | 0:abda4161bf6e | 4 | GDClass GD(ARD_MOSI, ARD_MISO, ARD_SCK, ARD_D9, USBTX, USBRX) ; |
TheChrisyd | 0:abda4161bf6e | 5 | |
TheChrisyd | 0:abda4161bf6e | 6 | |
TheChrisyd | 0:abda4161bf6e | 7 | // replicate a 2-bit color across the whole byte. Optimization for setpixel |
TheChrisyd | 0:abda4161bf6e | 8 | byte replicate(byte color) |
TheChrisyd | 0:abda4161bf6e | 9 | { |
TheChrisyd | 0:abda4161bf6e | 10 | return (color << 6) | (color << 4) | (color << 2) | color; |
TheChrisyd | 0:abda4161bf6e | 11 | } |
TheChrisyd | 0:abda4161bf6e | 12 | |
TheChrisyd | 0:abda4161bf6e | 13 | // Set pixel at (x,y) to color. (note that color is replicated). |
TheChrisyd | 0:abda4161bf6e | 14 | void setpixel(byte x, byte y, byte color) |
TheChrisyd | 0:abda4161bf6e | 15 | { |
TheChrisyd | 0:abda4161bf6e | 16 | /* |
TheChrisyd | 0:abda4161bf6e | 17 | Because of the way the sprites are laid out in setup(), it's not too |
TheChrisyd | 0:abda4161bf6e | 18 | hard to translate the pixel (x,y) to an address and mask. Taking the |
TheChrisyd | 0:abda4161bf6e | 19 | two byte values as x7-x0 and y7-y0, the address of the pixel is: |
TheChrisyd | 0:abda4161bf6e | 20 | |
TheChrisyd | 0:abda4161bf6e | 21 | x5 x4 y7 y6 y5 y4 y3 y2 y1 y0 x3 x2 x1 x0 |
TheChrisyd | 0:abda4161bf6e | 22 | |
TheChrisyd | 0:abda4161bf6e | 23 | (x6, x7) gives the value of the mask. |
TheChrisyd | 0:abda4161bf6e | 24 | */ |
TheChrisyd | 0:abda4161bf6e | 25 | unsigned int addr = RAM_SPRIMG | (x & 0xf) | (y << 4) | ((x & 0x30) << 8); |
TheChrisyd | 0:abda4161bf6e | 26 | byte mask = 0xc0 >> ((x >> 5) & 6); |
TheChrisyd | 0:abda4161bf6e | 27 | GD.wr(addr, (GD.rd(addr) & ~mask) | (color & mask)); |
TheChrisyd | 0:abda4161bf6e | 28 | } |
TheChrisyd | 0:abda4161bf6e | 29 | |
TheChrisyd | 0:abda4161bf6e | 30 | // Draw color line from (x0,y0) to (x1,y1). |
TheChrisyd | 0:abda4161bf6e | 31 | void line(byte x0, byte y0, byte x1, byte y1, byte color) |
TheChrisyd | 0:abda4161bf6e | 32 | { |
TheChrisyd | 0:abda4161bf6e | 33 | byte swap; |
TheChrisyd | 0:abda4161bf6e | 34 | #define SWAP(a, b) (swap = (a), (a) = (b), (b) = swap) |
TheChrisyd | 0:abda4161bf6e | 35 | |
TheChrisyd | 0:abda4161bf6e | 36 | color = replicate(color); |
TheChrisyd | 0:abda4161bf6e | 37 | byte steep = abs(y1 - y0) > abs(x1 - x0); |
TheChrisyd | 0:abda4161bf6e | 38 | if (steep) { |
TheChrisyd | 0:abda4161bf6e | 39 | SWAP(x0, y0); |
TheChrisyd | 0:abda4161bf6e | 40 | SWAP(x1, y1); |
TheChrisyd | 0:abda4161bf6e | 41 | } |
TheChrisyd | 0:abda4161bf6e | 42 | if (x0 > x1) { |
TheChrisyd | 0:abda4161bf6e | 43 | SWAP(x0, x1); |
TheChrisyd | 0:abda4161bf6e | 44 | SWAP(y0, y1); |
TheChrisyd | 0:abda4161bf6e | 45 | } |
TheChrisyd | 0:abda4161bf6e | 46 | int deltax = x1 - x0; |
TheChrisyd | 0:abda4161bf6e | 47 | int deltay = abs(y1 - y0); |
TheChrisyd | 0:abda4161bf6e | 48 | int error = deltax / 2; |
TheChrisyd | 0:abda4161bf6e | 49 | signed char ystep; |
TheChrisyd | 0:abda4161bf6e | 50 | if (y0 < y1) |
TheChrisyd | 0:abda4161bf6e | 51 | { |
TheChrisyd | 0:abda4161bf6e | 52 | ystep = 1; |
TheChrisyd | 0:abda4161bf6e | 53 | } |
TheChrisyd | 0:abda4161bf6e | 54 | else |
TheChrisyd | 0:abda4161bf6e | 55 | { |
TheChrisyd | 0:abda4161bf6e | 56 | ystep = -1; |
TheChrisyd | 0:abda4161bf6e | 57 | } |
TheChrisyd | 0:abda4161bf6e | 58 | byte x; |
TheChrisyd | 0:abda4161bf6e | 59 | byte y = y0; |
TheChrisyd | 0:abda4161bf6e | 60 | for (x = x0; x < x1; x++) |
TheChrisyd | 0:abda4161bf6e | 61 | { |
TheChrisyd | 0:abda4161bf6e | 62 | if (steep) |
TheChrisyd | 0:abda4161bf6e | 63 | { |
TheChrisyd | 0:abda4161bf6e | 64 | setpixel(y, x, color); |
TheChrisyd | 0:abda4161bf6e | 65 | } |
TheChrisyd | 0:abda4161bf6e | 66 | else |
TheChrisyd | 0:abda4161bf6e | 67 | { |
TheChrisyd | 0:abda4161bf6e | 68 | setpixel(x, y, color); |
TheChrisyd | 0:abda4161bf6e | 69 | } |
TheChrisyd | 0:abda4161bf6e | 70 | error -= deltay; |
TheChrisyd | 0:abda4161bf6e | 71 | if (error < 0) |
TheChrisyd | 0:abda4161bf6e | 72 | { |
TheChrisyd | 0:abda4161bf6e | 73 | y += ystep; |
TheChrisyd | 0:abda4161bf6e | 74 | error += deltax; |
TheChrisyd | 0:abda4161bf6e | 75 | } |
TheChrisyd | 0:abda4161bf6e | 76 | } |
TheChrisyd | 0:abda4161bf6e | 77 | } |
TheChrisyd | 0:abda4161bf6e | 78 | |
TheChrisyd | 0:abda4161bf6e | 79 | struct point { |
TheChrisyd | 0:abda4161bf6e | 80 | int x, y; |
TheChrisyd | 0:abda4161bf6e | 81 | signed char xv, yv; |
TheChrisyd | 0:abda4161bf6e | 82 | }; |
TheChrisyd | 0:abda4161bf6e | 83 | static struct point triangle[3]; |
TheChrisyd | 0:abda4161bf6e | 84 | |
TheChrisyd | 0:abda4161bf6e | 85 | #define RANDOM_RGB() RGB(rand()%256,rand()%256,rand()%256) |
TheChrisyd | 0:abda4161bf6e | 86 | |
TheChrisyd | 0:abda4161bf6e | 87 | // Restart the drawing |
TheChrisyd | 0:abda4161bf6e | 88 | static void restart() |
TheChrisyd | 0:abda4161bf6e | 89 | { |
TheChrisyd | 0:abda4161bf6e | 90 | // Clear the screen |
TheChrisyd | 0:abda4161bf6e | 91 | GD.fill(RAM_SPRIMG, 0, 16384); |
TheChrisyd | 0:abda4161bf6e | 92 | |
TheChrisyd | 0:abda4161bf6e | 93 | // Position triangle at random |
TheChrisyd | 0:abda4161bf6e | 94 | byte i; |
TheChrisyd | 0:abda4161bf6e | 95 | for (i = 0; i < 3; i++) { |
TheChrisyd | 0:abda4161bf6e | 96 | triangle[i].x = 3 + rand()%250; |
TheChrisyd | 0:abda4161bf6e | 97 | triangle[i].y = 3 + rand()%250; |
TheChrisyd | 0:abda4161bf6e | 98 | } |
TheChrisyd | 0:abda4161bf6e | 99 | triangle[0].xv = 1; |
TheChrisyd | 0:abda4161bf6e | 100 | triangle[0].yv = 1; |
TheChrisyd | 0:abda4161bf6e | 101 | triangle[1].xv = -1; |
TheChrisyd | 0:abda4161bf6e | 102 | triangle[1].yv = 1; |
TheChrisyd | 0:abda4161bf6e | 103 | triangle[2].xv = 1; |
TheChrisyd | 0:abda4161bf6e | 104 | triangle[2].yv = -1; |
TheChrisyd | 0:abda4161bf6e | 105 | |
TheChrisyd | 0:abda4161bf6e | 106 | // Choose a random palette |
TheChrisyd | 0:abda4161bf6e | 107 | GD.wr16(PALETTE4A, RGB(0,0,0)); |
TheChrisyd | 0:abda4161bf6e | 108 | GD.wr16(PALETTE4A + 2, RANDOM_RGB()); |
TheChrisyd | 0:abda4161bf6e | 109 | GD.wr16(PALETTE4A + 4, RANDOM_RGB()); |
TheChrisyd | 0:abda4161bf6e | 110 | GD.wr16(PALETTE4A + 6, RANDOM_RGB()); |
TheChrisyd | 0:abda4161bf6e | 111 | } |
TheChrisyd | 0:abda4161bf6e | 112 | |
TheChrisyd | 0:abda4161bf6e | 113 | void setup() |
TheChrisyd | 0:abda4161bf6e | 114 | { |
TheChrisyd | 0:abda4161bf6e | 115 | int i; |
TheChrisyd | 0:abda4161bf6e | 116 | |
TheChrisyd | 0:abda4161bf6e | 117 | GD.begin(); |
TheChrisyd | 0:abda4161bf6e | 118 | GD.ascii(); |
TheChrisyd | 0:abda4161bf6e | 119 | GD.putstr(0, 0,"Bitmap demonstration"); |
TheChrisyd | 0:abda4161bf6e | 120 | |
TheChrisyd | 0:abda4161bf6e | 121 | // Draw 256 sprites left to right, top to bottom, all in 4-color |
TheChrisyd | 0:abda4161bf6e | 122 | // palette mode. By doing them in column-wise order, the address |
TheChrisyd | 0:abda4161bf6e | 123 | // calculation in setpixel is made simpler. |
TheChrisyd | 0:abda4161bf6e | 124 | // First 64 use bits 0-1, next 64 use bits 2-4, etc. |
TheChrisyd | 0:abda4161bf6e | 125 | // This gives a 256 x 256 4-color bitmap. |
TheChrisyd | 0:abda4161bf6e | 126 | |
TheChrisyd | 0:abda4161bf6e | 127 | for (i = 0; i < 256; i++) { |
TheChrisyd | 0:abda4161bf6e | 128 | int x = 72 + 16 * ((i >> 4) & 15); |
TheChrisyd | 0:abda4161bf6e | 129 | int y = 22 + 16 * (i & 15); |
TheChrisyd | 0:abda4161bf6e | 130 | int image = i & 63; /* image 0-63 */ |
TheChrisyd | 0:abda4161bf6e | 131 | int pal = 3 - (i >> 6); /* palettes bits in columns 3,2,1,0 */ |
TheChrisyd | 0:abda4161bf6e | 132 | GD.sprite(i, x, y, image, 0x8 | (pal << 1), 0); |
TheChrisyd | 0:abda4161bf6e | 133 | } |
TheChrisyd | 0:abda4161bf6e | 134 | restart(); |
TheChrisyd | 0:abda4161bf6e | 135 | } |
TheChrisyd | 0:abda4161bf6e | 136 | |
TheChrisyd | 0:abda4161bf6e | 137 | int main() |
TheChrisyd | 0:abda4161bf6e | 138 | { |
TheChrisyd | 0:abda4161bf6e | 139 | setup(); |
TheChrisyd | 0:abda4161bf6e | 140 | while(1) |
TheChrisyd | 0:abda4161bf6e | 141 | { |
TheChrisyd | 0:abda4161bf6e | 142 | static byte color; |
TheChrisyd | 0:abda4161bf6e | 143 | |
TheChrisyd | 0:abda4161bf6e | 144 | if (rand()%1000 == 0) |
TheChrisyd | 0:abda4161bf6e | 145 | { |
TheChrisyd | 0:abda4161bf6e | 146 | restart(); |
TheChrisyd | 0:abda4161bf6e | 147 | } |
TheChrisyd | 0:abda4161bf6e | 148 | line(triangle[0].x, triangle[0].y, triangle[1].x, triangle[1].y, color); |
TheChrisyd | 0:abda4161bf6e | 149 | line(triangle[1].x, triangle[1].y, triangle[2].x, triangle[2].y, color); |
TheChrisyd | 0:abda4161bf6e | 150 | line(triangle[2].x, triangle[2].y, triangle[0].x, triangle[0].y, color); |
TheChrisyd | 0:abda4161bf6e | 151 | color = (color + 1) & 3; |
TheChrisyd | 0:abda4161bf6e | 152 | byte i; |
TheChrisyd | 0:abda4161bf6e | 153 | for (i = 0; i < 3; i++) |
TheChrisyd | 0:abda4161bf6e | 154 | { |
TheChrisyd | 0:abda4161bf6e | 155 | triangle[i].x += triangle[i].xv; |
TheChrisyd | 0:abda4161bf6e | 156 | triangle[i].y += triangle[i].yv; |
TheChrisyd | 0:abda4161bf6e | 157 | if (triangle[i].x == 0 || triangle[i].x == 255) |
TheChrisyd | 0:abda4161bf6e | 158 | { |
TheChrisyd | 0:abda4161bf6e | 159 | triangle[i].xv = -triangle[i].xv; |
TheChrisyd | 0:abda4161bf6e | 160 | } |
TheChrisyd | 0:abda4161bf6e | 161 | if (triangle[i].y == 0 || triangle[i].y == 255) |
TheChrisyd | 0:abda4161bf6e | 162 | { |
TheChrisyd | 0:abda4161bf6e | 163 | triangle[i].yv = -triangle[i].yv; |
TheChrisyd | 0:abda4161bf6e | 164 | } |
TheChrisyd | 0:abda4161bf6e | 165 | } |
TheChrisyd | 0:abda4161bf6e | 166 | } |
TheChrisyd | 0:abda4161bf6e | 167 | } |