Ryan Savitski
/
LEDsnake
LED screen snake as an example of 48x48 panelspace working.
main.cpp@0:b38330b559d4, 2012-03-22 (annotated)
- Committer:
- rsavitski
- Date:
- Thu Mar 22 13:20:53 2012 +0000
- Revision:
- 0:b38330b559d4
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rsavitski | 0:b38330b559d4 | 1 | #include "mbed.h" |
rsavitski | 0:b38330b559d4 | 2 | #include "ledScreen.h" |
rsavitski | 0:b38330b559d4 | 3 | |
rsavitski | 0:b38330b559d4 | 4 | // screen instance |
rsavitski | 0:b38330b559d4 | 5 | ledScreen screen; |
rsavitski | 0:b38330b559d4 | 6 | |
rsavitski | 0:b38330b559d4 | 7 | // controller |
rsavitski | 0:b38330b559d4 | 8 | AnalogIn xJoy(p20); |
rsavitski | 0:b38330b559d4 | 9 | AnalogIn yJoy(p19); |
rsavitski | 0:b38330b559d4 | 10 | DigitalIn Abutton(p22); |
rsavitski | 0:b38330b559d4 | 11 | DigitalIn Bbutton(p21); |
rsavitski | 0:b38330b559d4 | 12 | |
rsavitski | 0:b38330b559d4 | 13 | //snake |
rsavitski | 0:b38330b559d4 | 14 | struct snakeBitPos |
rsavitski | 0:b38330b559d4 | 15 | { |
rsavitski | 0:b38330b559d4 | 16 | signed char x; |
rsavitski | 0:b38330b559d4 | 17 | signed char y; |
rsavitski | 0:b38330b559d4 | 18 | }; |
rsavitski | 0:b38330b559d4 | 19 | |
rsavitski | 0:b38330b559d4 | 20 | // sin lookup table and related functions |
rsavitski | 0:b38330b559d4 | 21 | unsigned char sinlut[256]; |
rsavitski | 0:b38330b559d4 | 22 | |
rsavitski | 0:b38330b559d4 | 23 | void initSinLut() { |
rsavitski | 0:b38330b559d4 | 24 | for (int i=0; i<256; i++) |
rsavitski | 0:b38330b559d4 | 25 | sinlut[i] = cos((float)i / 256.0 * (3.14159265 * 2))*127 + 128; |
rsavitski | 0:b38330b559d4 | 26 | } |
rsavitski | 0:b38330b559d4 | 27 | |
rsavitski | 0:b38330b559d4 | 28 | inline unsigned char lut_sin(int x) { |
rsavitski | 0:b38330b559d4 | 29 | |
rsavitski | 0:b38330b559d4 | 30 | return (x>0)?sinlut[x%256]:sinlut[(-x)%256]; |
rsavitski | 0:b38330b559d4 | 31 | } |
rsavitski | 0:b38330b559d4 | 32 | |
rsavitski | 0:b38330b559d4 | 33 | |
rsavitski | 0:b38330b559d4 | 34 | // Example frame makes: |
rsavitski | 0:b38330b559d4 | 35 | |
rsavitski | 0:b38330b559d4 | 36 | |
rsavitski | 0:b38330b559d4 | 37 | //rainbow |
rsavitski | 0:b38330b559d4 | 38 | void makeFrame1(unsigned char* data) { |
rsavitski | 0:b38330b559d4 | 39 | |
rsavitski | 0:b38330b559d4 | 40 | static int time=0; |
rsavitski | 0:b38330b559d4 | 41 | time++; |
rsavitski | 0:b38330b559d4 | 42 | |
rsavitski | 0:b38330b559d4 | 43 | // override data with a intensity gradient test pattern |
rsavitski | 0:b38330b559d4 | 44 | for (int x=0; x<3*16; x++) { |
rsavitski | 0:b38330b559d4 | 45 | for (int y=0; y<48; y++) { |
rsavitski | 0:b38330b559d4 | 46 | |
rsavitski | 0:b38330b559d4 | 47 | int i = (x + y*(16*3)) * 3; // figure out the memory location |
rsavitski | 0:b38330b559d4 | 48 | |
rsavitski | 0:b38330b559d4 | 49 | data[i] = lut_sin((x+y)*255/48+(time/2)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 50 | data[i+1] = lut_sin(((x+y)*255/48+(time/2)+ 85)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 51 | data[i+2] = lut_sin(((x+y)*255/48+(time/2)+170)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 52 | } |
rsavitski | 0:b38330b559d4 | 53 | } |
rsavitski | 0:b38330b559d4 | 54 | |
rsavitski | 0:b38330b559d4 | 55 | } |
rsavitski | 0:b38330b559d4 | 56 | |
rsavitski | 0:b38330b559d4 | 57 | //cool lines |
rsavitski | 0:b38330b559d4 | 58 | void makeFrame2(unsigned char* data) { |
rsavitski | 0:b38330b559d4 | 59 | |
rsavitski | 0:b38330b559d4 | 60 | static int time=0; |
rsavitski | 0:b38330b559d4 | 61 | time++; |
rsavitski | 0:b38330b559d4 | 62 | |
rsavitski | 0:b38330b559d4 | 63 | // override data with a intensity gradient test pattern |
rsavitski | 0:b38330b559d4 | 64 | for (int x=0; x<3*16; x++) { |
rsavitski | 0:b38330b559d4 | 65 | for (int y=0; y<16; y++) { |
rsavitski | 0:b38330b559d4 | 66 | |
rsavitski | 0:b38330b559d4 | 67 | int i = (x + y*(16*3)) * 3; // figure out the memory location |
rsavitski | 0:b38330b559d4 | 68 | |
rsavitski | 0:b38330b559d4 | 69 | data[i] = lut_sin(x*255/48+(time)%256 + y*16); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 70 | data[i+1] = lut_sin(x*255/48+(time)%256 + y*16 + 85); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 71 | data[i+2] = lut_sin(x*255/48+(time)%256 + y*16 + 170); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 72 | } |
rsavitski | 0:b38330b559d4 | 73 | } |
rsavitski | 0:b38330b559d4 | 74 | |
rsavitski | 0:b38330b559d4 | 75 | } |
rsavitski | 0:b38330b559d4 | 76 | |
rsavitski | 0:b38330b559d4 | 77 | // static gradients |
rsavitski | 0:b38330b559d4 | 78 | void makeFrame3(unsigned char* data) { |
rsavitski | 0:b38330b559d4 | 79 | |
rsavitski | 0:b38330b559d4 | 80 | static int time=0; |
rsavitski | 0:b38330b559d4 | 81 | time++; |
rsavitski | 0:b38330b559d4 | 82 | |
rsavitski | 0:b38330b559d4 | 83 | // override data with a intensity gradient test pattern |
rsavitski | 0:b38330b559d4 | 84 | for (int x=0; x<3*16; x++) { |
rsavitski | 0:b38330b559d4 | 85 | for (int y=0; y<16; y++) { |
rsavitski | 0:b38330b559d4 | 86 | |
rsavitski | 0:b38330b559d4 | 87 | int i = (x + y*(16*3)) * 3; // figure out the memory location |
rsavitski | 0:b38330b559d4 | 88 | |
rsavitski | 0:b38330b559d4 | 89 | data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 90 | data[i+1] = 0; // green |
rsavitski | 0:b38330b559d4 | 91 | data[i+2] = y*256/16; //(i/3)%256 ; // blue |
rsavitski | 0:b38330b559d4 | 92 | } |
rsavitski | 0:b38330b559d4 | 93 | } |
rsavitski | 0:b38330b559d4 | 94 | |
rsavitski | 0:b38330b559d4 | 95 | } |
rsavitski | 0:b38330b559d4 | 96 | |
rsavitski | 0:b38330b559d4 | 97 | void makeEmptyFrame(unsigned char* data) |
rsavitski | 0:b38330b559d4 | 98 | { |
rsavitski | 0:b38330b559d4 | 99 | for (int x=0; x<3*16; x++) { |
rsavitski | 0:b38330b559d4 | 100 | for (int y=0; y<3*16; y++) { |
rsavitski | 0:b38330b559d4 | 101 | |
rsavitski | 0:b38330b559d4 | 102 | int i = (x + y*(16*3)) * 3; // figure out the memory location |
rsavitski | 0:b38330b559d4 | 103 | |
rsavitski | 0:b38330b559d4 | 104 | data[i] = 0; |
rsavitski | 0:b38330b559d4 | 105 | data[i+1] = 0; |
rsavitski | 0:b38330b559d4 | 106 | data[i+2] = 0; |
rsavitski | 0:b38330b559d4 | 107 | } |
rsavitski | 0:b38330b559d4 | 108 | } |
rsavitski | 0:b38330b559d4 | 109 | |
rsavitski | 0:b38330b559d4 | 110 | } |
rsavitski | 0:b38330b559d4 | 111 | |
rsavitski | 0:b38330b559d4 | 112 | void stepSnake(unsigned char* data) |
rsavitski | 0:b38330b559d4 | 113 | { |
rsavitski | 0:b38330b559d4 | 114 | static snakeBitPos dotLoc; // going to be the dot |
rsavitski | 0:b38330b559d4 | 115 | static unsigned short length=2; |
rsavitski | 0:b38330b559d4 | 116 | static unsigned char dir; |
rsavitski | 0:b38330b559d4 | 117 | static snakeBitPos snakeArr[100]; |
rsavitski | 0:b38330b559d4 | 118 | |
rsavitski | 0:b38330b559d4 | 119 | static bool firstCall=true; |
rsavitski | 0:b38330b559d4 | 120 | if (firstCall) { snakeArr[0].x=20; snakeArr[0].y=20; firstCall=false; dotLoc.x=rand()%48; dotLoc.y=rand()%48; } |
rsavitski | 0:b38330b559d4 | 121 | static bool gameover=false; |
rsavitski | 0:b38330b559d4 | 122 | static short speed_n = 50; |
rsavitski | 0:b38330b559d4 | 123 | |
rsavitski | 0:b38330b559d4 | 124 | if (!gameover) |
rsavitski | 0:b38330b559d4 | 125 | { |
rsavitski | 0:b38330b559d4 | 126 | |
rsavitski | 0:b38330b559d4 | 127 | static unsigned short time=0; |
rsavitski | 0:b38330b559d4 | 128 | time++; |
rsavitski | 0:b38330b559d4 | 129 | time = time%(speed_n/2); // smaller constant = higher speed |
rsavitski | 0:b38330b559d4 | 130 | |
rsavitski | 0:b38330b559d4 | 131 | |
rsavitski | 0:b38330b559d4 | 132 | // updating direction on every invocation |
rsavitski | 0:b38330b559d4 | 133 | float xReading = xJoy.read(); |
rsavitski | 0:b38330b559d4 | 134 | float yReading = yJoy.read(); |
rsavitski | 0:b38330b559d4 | 135 | |
rsavitski | 0:b38330b559d4 | 136 | if (xReading > 0.9 && dir != 1) |
rsavitski | 0:b38330b559d4 | 137 | {dir = 0; } |
rsavitski | 0:b38330b559d4 | 138 | else if(xReading < 0.3 && dir != 0) |
rsavitski | 0:b38330b559d4 | 139 | {dir = 1; } |
rsavitski | 0:b38330b559d4 | 140 | else if(yReading > 0.9 && dir != 3) |
rsavitski | 0:b38330b559d4 | 141 | {dir = 2; } |
rsavitski | 0:b38330b559d4 | 142 | else if(yReading < 0.3 && dir != 2) |
rsavitski | 0:b38330b559d4 | 143 | {dir = 3; } |
rsavitski | 0:b38330b559d4 | 144 | |
rsavitski | 0:b38330b559d4 | 145 | |
rsavitski | 0:b38330b559d4 | 146 | // moving the snake forward |
rsavitski | 0:b38330b559d4 | 147 | if (time == 0) |
rsavitski | 0:b38330b559d4 | 148 | { |
rsavitski | 0:b38330b559d4 | 149 | for (int j=length; j>0; j--) |
rsavitski | 0:b38330b559d4 | 150 | { |
rsavitski | 0:b38330b559d4 | 151 | snakeArr[j]=snakeArr[j-1]; |
rsavitski | 0:b38330b559d4 | 152 | } |
rsavitski | 0:b38330b559d4 | 153 | switch(dir) |
rsavitski | 0:b38330b559d4 | 154 | { |
rsavitski | 0:b38330b559d4 | 155 | case(0): |
rsavitski | 0:b38330b559d4 | 156 | (snakeArr[0]).x++; |
rsavitski | 0:b38330b559d4 | 157 | break; |
rsavitski | 0:b38330b559d4 | 158 | case(1): |
rsavitski | 0:b38330b559d4 | 159 | (snakeArr[0]).x--; |
rsavitski | 0:b38330b559d4 | 160 | break; |
rsavitski | 0:b38330b559d4 | 161 | case(2): |
rsavitski | 0:b38330b559d4 | 162 | (snakeArr[0]).y++; |
rsavitski | 0:b38330b559d4 | 163 | break; |
rsavitski | 0:b38330b559d4 | 164 | case(3): |
rsavitski | 0:b38330b559d4 | 165 | (snakeArr[0]).y--; |
rsavitski | 0:b38330b559d4 | 166 | break; |
rsavitski | 0:b38330b559d4 | 167 | } |
rsavitski | 0:b38330b559d4 | 168 | |
rsavitski | 0:b38330b559d4 | 169 | // wrapping |
rsavitski | 0:b38330b559d4 | 170 | if (snakeArr[0].x==-1) snakeArr[0].x=47; |
rsavitski | 0:b38330b559d4 | 171 | if (snakeArr[0].x==48) snakeArr[0].x=0; |
rsavitski | 0:b38330b559d4 | 172 | if (snakeArr[0].y==48) snakeArr[0].y=0; |
rsavitski | 0:b38330b559d4 | 173 | if (snakeArr[0].y==-1) snakeArr[0].y=47; |
rsavitski | 0:b38330b559d4 | 174 | |
rsavitski | 0:b38330b559d4 | 175 | if (snakeArr[0].y==dotLoc.y && snakeArr[0].x==dotLoc.x) |
rsavitski | 0:b38330b559d4 | 176 | { |
rsavitski | 0:b38330b559d4 | 177 | dotLoc.x = rand()%48; |
rsavitski | 0:b38330b559d4 | 178 | dotLoc.y = rand()%48; |
rsavitski | 0:b38330b559d4 | 179 | length++; |
rsavitski | 0:b38330b559d4 | 180 | speed_n--; if (speed_n<2) speed_n=2; |
rsavitski | 0:b38330b559d4 | 181 | } |
rsavitski | 0:b38330b559d4 | 182 | |
rsavitski | 0:b38330b559d4 | 183 | // outputting |
rsavitski | 0:b38330b559d4 | 184 | int i=0; |
rsavitski | 0:b38330b559d4 | 185 | // killing own tail (no need to zero whole screen) |
rsavitski | 0:b38330b559d4 | 186 | i = (snakeArr[length].x+(snakeArr[length].y)*48)*3; |
rsavitski | 0:b38330b559d4 | 187 | data[i] = 0; |
rsavitski | 0:b38330b559d4 | 188 | data[i+2] = 0; |
rsavitski | 0:b38330b559d4 | 189 | |
rsavitski | 0:b38330b559d4 | 190 | // new head alone (no need for looping) |
rsavitski | 0:b38330b559d4 | 191 | i = (snakeArr[0].x+(snakeArr[0].y)*48)*3; |
rsavitski | 0:b38330b559d4 | 192 | |
rsavitski | 0:b38330b559d4 | 193 | // if hitting self, game over |
rsavitski | 0:b38330b559d4 | 194 | if (data[i]==255) {data[i+1] = 255; gameover=true;} |
rsavitski | 0:b38330b559d4 | 195 | |
rsavitski | 0:b38330b559d4 | 196 | data[i] = 255; |
rsavitski | 0:b38330b559d4 | 197 | data[i+2] = 127; |
rsavitski | 0:b38330b559d4 | 198 | |
rsavitski | 0:b38330b559d4 | 199 | data[(dotLoc.x+dotLoc.y*48)*3 +2] = 255; |
rsavitski | 0:b38330b559d4 | 200 | } |
rsavitski | 0:b38330b559d4 | 201 | } |
rsavitski | 0:b38330b559d4 | 202 | } |
rsavitski | 0:b38330b559d4 | 203 | |
rsavitski | 0:b38330b559d4 | 204 | |
rsavitski | 0:b38330b559d4 | 205 | void makeFrame33(unsigned char* data) { |
rsavitski | 0:b38330b559d4 | 206 | |
rsavitski | 0:b38330b559d4 | 207 | static int time=0; |
rsavitski | 0:b38330b559d4 | 208 | time++; |
rsavitski | 0:b38330b559d4 | 209 | |
rsavitski | 0:b38330b559d4 | 210 | for (int x=0; x<3*16; x++) { |
rsavitski | 0:b38330b559d4 | 211 | for (int y=0; y<48; y++) { |
rsavitski | 0:b38330b559d4 | 212 | |
rsavitski | 0:b38330b559d4 | 213 | int i = (x + y*(16*3)) * 3; // figure out the memory location |
rsavitski | 0:b38330b559d4 | 214 | |
rsavitski | 0:b38330b559d4 | 215 | data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ; // red |
rsavitski | 0:b38330b559d4 | 216 | data[i+1] = 0; // green |
rsavitski | 0:b38330b559d4 | 217 | data[i+2] = y*256/48; //(i/3)%256 ; // blue |
rsavitski | 0:b38330b559d4 | 218 | } |
rsavitski | 0:b38330b559d4 | 219 | } |
rsavitski | 0:b38330b559d4 | 220 | } |
rsavitski | 0:b38330b559d4 | 221 | |
rsavitski | 0:b38330b559d4 | 222 | int main() |
rsavitski | 0:b38330b559d4 | 223 | { |
rsavitski | 0:b38330b559d4 | 224 | |
rsavitski | 0:b38330b559d4 | 225 | // framebuffer on client side |
rsavitski | 0:b38330b559d4 | 226 | unsigned char imageSource[256*3*3*3] = { 0 }; |
rsavitski | 0:b38330b559d4 | 227 | |
rsavitski | 0:b38330b559d4 | 228 | // prepare sin lookup table (optional) |
rsavitski | 0:b38330b559d4 | 229 | initSinLut(); |
rsavitski | 0:b38330b559d4 | 230 | |
rsavitski | 0:b38330b559d4 | 231 | // start the screen output, which will keep outputting the frames that are in its internal buffer (updated via .transformFrame) |
rsavitski | 0:b38330b559d4 | 232 | screen.start(); |
rsavitski | 0:b38330b559d4 | 233 | |
rsavitski | 0:b38330b559d4 | 234 | makeEmptyFrame(imageSource); |
rsavitski | 0:b38330b559d4 | 235 | |
rsavitski | 0:b38330b559d4 | 236 | while (1) { |
rsavitski | 0:b38330b559d4 | 237 | |
rsavitski | 0:b38330b559d4 | 238 | stepSnake(imageSource); // prepare framebuffer with current frame |
rsavitski | 0:b38330b559d4 | 239 | screen.transformFrame(imageSource); // write framebuffer to output framebuffer |
rsavitski | 0:b38330b559d4 | 240 | wait_ms(0.5); // slow down the framerate (optional) |
rsavitski | 0:b38330b559d4 | 241 | } |
rsavitski | 0:b38330b559d4 | 242 | |
rsavitski | 0:b38330b559d4 | 243 | } |