Ryan Savitski
/
LEDsnake
LED screen snake as an example of 48x48 panelspace working.
Diff: main.cpp
- Revision:
- 0:b38330b559d4
diff -r 000000000000 -r b38330b559d4 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Mar 22 13:20:53 2012 +0000 @@ -0,0 +1,243 @@ +#include "mbed.h" +#include "ledScreen.h" + +// screen instance +ledScreen screen; + +// controller +AnalogIn xJoy(p20); +AnalogIn yJoy(p19); +DigitalIn Abutton(p22); +DigitalIn Bbutton(p21); + +//snake +struct snakeBitPos +{ + signed char x; + signed char y; +}; + +// sin lookup table and related functions +unsigned char sinlut[256]; + +void initSinLut() { + for (int i=0; i<256; i++) + sinlut[i] = cos((float)i / 256.0 * (3.14159265 * 2))*127 + 128; +} + +inline unsigned char lut_sin(int x) { + + return (x>0)?sinlut[x%256]:sinlut[(-x)%256]; +} + + +// Example frame makes: + + +//rainbow +void makeFrame1(unsigned char* data) { + + static int time=0; + time++; + + // override data with a intensity gradient test pattern + for (int x=0; x<3*16; x++) { + for (int y=0; y<48; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = lut_sin((x+y)*255/48+(time/2)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+1] = lut_sin(((x+y)*255/48+(time/2)+ 85)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+2] = lut_sin(((x+y)*255/48+(time/2)+170)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + } + } + +} + +//cool lines +void makeFrame2(unsigned char* data) { + + static int time=0; + time++; + + // override data with a intensity gradient test pattern + for (int x=0; x<3*16; x++) { + for (int y=0; y<16; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = lut_sin(x*255/48+(time)%256 + y*16); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+1] = lut_sin(x*255/48+(time)%256 + y*16 + 85); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+2] = lut_sin(x*255/48+(time)%256 + y*16 + 170); //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + } + } + +} + +// static gradients +void makeFrame3(unsigned char* data) { + + static int time=0; + time++; + + // override data with a intensity gradient test pattern + for (int x=0; x<3*16; x++) { + for (int y=0; y<16; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+1] = 0; // green + data[i+2] = y*256/16; //(i/3)%256 ; // blue + } + } + +} + +void makeEmptyFrame(unsigned char* data) +{ + for (int x=0; x<3*16; x++) { + for (int y=0; y<3*16; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = 0; + data[i+1] = 0; + data[i+2] = 0; + } + } + +} + +void stepSnake(unsigned char* data) +{ + static snakeBitPos dotLoc; // going to be the dot + static unsigned short length=2; + static unsigned char dir; + static snakeBitPos snakeArr[100]; + + static bool firstCall=true; + if (firstCall) { snakeArr[0].x=20; snakeArr[0].y=20; firstCall=false; dotLoc.x=rand()%48; dotLoc.y=rand()%48; } + static bool gameover=false; + static short speed_n = 50; + + if (!gameover) + { + + static unsigned short time=0; + time++; + time = time%(speed_n/2); // smaller constant = higher speed + + + // updating direction on every invocation + float xReading = xJoy.read(); + float yReading = yJoy.read(); + + if (xReading > 0.9 && dir != 1) + {dir = 0; } + else if(xReading < 0.3 && dir != 0) + {dir = 1; } + else if(yReading > 0.9 && dir != 3) + {dir = 2; } + else if(yReading < 0.3 && dir != 2) + {dir = 3; } + + + // moving the snake forward + if (time == 0) + { + for (int j=length; j>0; j--) + { + snakeArr[j]=snakeArr[j-1]; + } + switch(dir) + { + case(0): + (snakeArr[0]).x++; + break; + case(1): + (snakeArr[0]).x--; + break; + case(2): + (snakeArr[0]).y++; + break; + case(3): + (snakeArr[0]).y--; + break; + } + + // wrapping + if (snakeArr[0].x==-1) snakeArr[0].x=47; + if (snakeArr[0].x==48) snakeArr[0].x=0; + if (snakeArr[0].y==48) snakeArr[0].y=0; + if (snakeArr[0].y==-1) snakeArr[0].y=47; + + if (snakeArr[0].y==dotLoc.y && snakeArr[0].x==dotLoc.x) + { + dotLoc.x = rand()%48; + dotLoc.y = rand()%48; + length++; + speed_n--; if (speed_n<2) speed_n=2; + } + + // outputting + int i=0; + // killing own tail (no need to zero whole screen) + i = (snakeArr[length].x+(snakeArr[length].y)*48)*3; + data[i] = 0; + data[i+2] = 0; + + // new head alone (no need for looping) + i = (snakeArr[0].x+(snakeArr[0].y)*48)*3; + + // if hitting self, game over + if (data[i]==255) {data[i+1] = 255; gameover=true;} + + data[i] = 255; + data[i+2] = 127; + + data[(dotLoc.x+dotLoc.y*48)*3 +2] = 255; + } + } +} + + +void makeFrame33(unsigned char* data) { + + static int time=0; + time++; + + for (int x=0; x<3*16; x++) { + for (int y=0; y<48; y++) { + + int i = (x + y*(16*3)) * 3; // figure out the memory location + + data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ; // red + data[i+1] = 0; // green + data[i+2] = y*256/48; //(i/3)%256 ; // blue + } + } +} + +int main() +{ + + // framebuffer on client side + unsigned char imageSource[256*3*3*3] = { 0 }; + + // prepare sin lookup table (optional) + initSinLut(); + + // start the screen output, which will keep outputting the frames that are in its internal buffer (updated via .transformFrame) + screen.start(); + + makeEmptyFrame(imageSource); + + while (1) { + + stepSnake(imageSource); // prepare framebuffer with current frame + screen.transformFrame(imageSource); // write framebuffer to output framebuffer + wait_ms(0.5); // slow down the framerate (optional) + } + +} \ No newline at end of file