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

Dependencies:   mbed

Revision:
0:b38330b559d4
--- /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