LED screen snake as an example of 48x48 panelspace working.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "ledScreen.h"
00003 
00004 // screen instance
00005 ledScreen screen;
00006 
00007 // controller
00008 AnalogIn xJoy(p20);
00009 AnalogIn yJoy(p19);
00010 DigitalIn Abutton(p22);
00011 DigitalIn Bbutton(p21);
00012 
00013 //snake
00014 struct snakeBitPos
00015 {
00016     signed char x;
00017     signed char y;
00018 };
00019 
00020 // sin lookup table and related functions
00021 unsigned char sinlut[256];
00022 
00023 void initSinLut() {
00024     for (int i=0; i<256; i++)
00025         sinlut[i] = cos((float)i / 256.0 * (3.14159265 * 2))*127 + 128;
00026 }
00027 
00028 inline unsigned char lut_sin(int x) {
00029 
00030     return (x>0)?sinlut[x%256]:sinlut[(-x)%256];
00031 }
00032 
00033 
00034 // Example frame makes:
00035 
00036 
00037 //rainbow
00038 void makeFrame1(unsigned char* data) {
00039 
00040     static int time=0;
00041     time++;
00042     
00043     // override data with a intensity gradient test pattern
00044     for (int x=0; x<3*16; x++) {
00045         for (int y=0; y<48; y++) {
00046 
00047             int i = (x + y*(16*3)) * 3;  // figure out the memory location
00048 
00049             data[i] = lut_sin((x+y)*255/48+(time/2)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00050             data[i+1] = lut_sin(((x+y)*255/48+(time/2)+ 85)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00051             data[i+2] = lut_sin(((x+y)*255/48+(time/2)+170)%256); //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00052         }
00053     }
00054 
00055 }
00056 
00057 //cool lines
00058 void makeFrame2(unsigned char* data) {
00059 
00060     static int time=0;
00061     time++;
00062     
00063     // override data with a intensity gradient test pattern
00064     for (int x=0; x<3*16; x++) {
00065         for (int y=0; y<16; y++) {
00066 
00067             int i = (x + y*(16*3)) * 3;  // figure out the memory location
00068 
00069             data[i] = lut_sin(x*255/48+(time)%256 + y*16); //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00070             data[i+1] = lut_sin(x*255/48+(time)%256 + y*16 + 85); //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00071             data[i+2] = lut_sin(x*255/48+(time)%256 + y*16 + 170); //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00072         }
00073     }
00074 
00075 }
00076 
00077 // static gradients
00078 void makeFrame3(unsigned char* data) {
00079 
00080     static int time=0;
00081     time++;
00082 
00083     // override data with a intensity gradient test pattern
00084     for (int x=0; x<3*16; x++) {
00085         for (int y=0; y<16; y++) {
00086 
00087             int i = (x + y*(16*3)) * 3;  // figure out the memory location
00088 
00089             data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00090             data[i+1] = 0;  // green
00091             data[i+2] = y*256/16; //(i/3)%256 ; // blue
00092         }
00093     }
00094 
00095 }
00096 
00097 void makeEmptyFrame(unsigned char* data)
00098 {
00099    for (int x=0; x<3*16; x++) {
00100         for (int y=0; y<3*16; y++) {
00101 
00102             int i = (x + y*(16*3)) * 3;  // figure out the memory location
00103 
00104             data[i] = 0; 
00105             data[i+1] = 0;  
00106             data[i+2] = 0;
00107         }
00108     }
00109 
00110 }
00111 
00112 void stepSnake(unsigned char* data)
00113 {
00114     static snakeBitPos dotLoc; // going to be the dot
00115     static unsigned short length=2;
00116     static unsigned char dir;
00117     static snakeBitPos snakeArr[100];
00118     
00119     static bool firstCall=true;
00120     if (firstCall) { snakeArr[0].x=20; snakeArr[0].y=20; firstCall=false; dotLoc.x=rand()%48; dotLoc.y=rand()%48; }
00121     static bool gameover=false;
00122     static short speed_n = 50;
00123     
00124     if (!gameover)
00125     {
00126         
00127         static unsigned short time=0;
00128         time++;
00129         time = time%(speed_n/2); // smaller constant = higher speed
00130 
00131         
00132         // updating direction on every invocation
00133         float xReading = xJoy.read();
00134         float yReading = yJoy.read();
00135         
00136         if (xReading > 0.9 && dir != 1)
00137             {dir = 0; }
00138         else if(xReading < 0.3 && dir != 0)
00139             {dir = 1; }
00140         else if(yReading > 0.9 && dir != 3)
00141             {dir = 2; }
00142         else if(yReading < 0.3 && dir != 2)
00143             {dir = 3; }
00144             
00145             
00146         // moving the snake forward     
00147         if (time == 0)
00148         {
00149             for (int j=length; j>0; j--)
00150             {
00151                 snakeArr[j]=snakeArr[j-1];
00152             }
00153             switch(dir)
00154             {
00155                 case(0):
00156                     (snakeArr[0]).x++;
00157                 break;
00158                 case(1):
00159                     (snakeArr[0]).x--;
00160                 break;
00161                 case(2):
00162                     (snakeArr[0]).y++;
00163                 break;
00164                 case(3):
00165                     (snakeArr[0]).y--;
00166                 break;
00167             }
00168             
00169         // wrapping
00170         if (snakeArr[0].x==-1) snakeArr[0].x=47;
00171         if (snakeArr[0].x==48) snakeArr[0].x=0;
00172         if (snakeArr[0].y==48) snakeArr[0].y=0;
00173         if (snakeArr[0].y==-1) snakeArr[0].y=47;
00174 
00175         if (snakeArr[0].y==dotLoc.y && snakeArr[0].x==dotLoc.x)
00176         {
00177             dotLoc.x = rand()%48;
00178             dotLoc.y = rand()%48;
00179             length++;
00180             speed_n--; if (speed_n<2) speed_n=2;
00181         }   
00182        
00183         // outputting
00184         int i=0;  
00185         // killing own tail (no need to zero whole screen)
00186         i = (snakeArr[length].x+(snakeArr[length].y)*48)*3;
00187         data[i] = 0;
00188         data[i+2] = 0;
00189     
00190         // new head alone (no need for looping)
00191         i = (snakeArr[0].x+(snakeArr[0].y)*48)*3;
00192         
00193         // if hitting self, game over
00194         if (data[i]==255) {data[i+1] = 255; gameover=true;}
00195         
00196         data[i] = 255;
00197         data[i+2] = 127;
00198         
00199         data[(dotLoc.x+dotLoc.y*48)*3 +2] = 255;
00200         }
00201     }
00202 }
00203 
00204 
00205 void makeFrame33(unsigned char* data) {
00206 
00207     static int time=0;
00208     time++;
00209 
00210     for (int x=0; x<3*16; x++) {
00211         for (int y=0; y<48; y++) {
00212 
00213             int i = (x + y*(16*3)) * 3;  // figure out the memory location
00214 
00215             data[i] = x*256/48; //(sin((float)(x+time)/15.0)+1.0)*128 ;   // red
00216             data[i+1] = 0;  // green
00217             data[i+2] = y*256/48; //(i/3)%256 ; // blue
00218         }
00219     }
00220 }
00221  
00222 int main()
00223 {
00224 
00225     // framebuffer on client side
00226     unsigned char imageSource[256*3*3*3] = { 0 };
00227     
00228     // prepare sin lookup table (optional)
00229     initSinLut(); 
00230 
00231     // start the screen output, which will keep outputting the frames that are in its internal buffer (updated via .transformFrame)
00232     screen.start();
00233 
00234     makeEmptyFrame(imageSource);
00235 
00236     while (1) {
00237         
00238         stepSnake(imageSource);  // prepare framebuffer with current frame
00239         screen.transformFrame(imageSource); // write framebuffer to output framebuffer
00240         wait_ms(0.5); // slow down the framerate (optional)
00241     }
00242 
00243 }