View Single Post
Old 04-21-2012, 12:40 PM   #29
jmseight
Zealot
jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'jmseight knows the difference between 'who' and 'whom'
 
Posts: 130
Karma: 10000
Join Date: Mar 2012
Device: Kindle 3G, Kindle Touch 3G, iRiver Story HD, Sony Reader
Hi,

Here is one that uses dithering.

I incremented the color every segment, and made every pixel width 2 to see the dithering.

EDIT: Fixed bug in color.

Code:
//====================================================
// simplePixelDemo 1.0 - random walk demo
// Copyright (C) 2012 by geekmaster, with MIT license:
// Copyright (C) 2012 by kiri, with MIT license:
// http://www.opensource.org/licenses/mit-license.php
//----------------------------------------------------
//  The speed is limited by the eink device drivers.
//  Newer kindle models are faster, but need delays.
//  This was tested on DX, DXG, K3, K5(touch).
//----------------------------------------------------

#include <stdio.h>      // printf
#include <stdlib.h>    // malloc, free, atoi
#include <string.h>   // memset, memcpy
#include <unistd.h>  // usleep
#include <fcntl.h>  // open, close, write
#include <time.h>  // time
#include <sys/ioctl.h>   // ioctl
#include <sys/time.h>   // gettime
#include <sys/mman.h>  // mmap, munmap
#include <linux/fb.h> // screeninfo

#define FPS 5 // max frames/sec
#define LENGTH 25000
#define STEP 1250

enum eupd_op { EUPD_OPEN,EUPD_CLOSE,EUPD_UPDATE };
typedef unsigned char u8;
typedef unsigned int u32;

// function prototypes
inline void setpx(int,int,int);
void setbx(int,int,int);
int eupdate(int);
int getmsec(void);

// global var7
u32 mpu=200;      // msec/update
u8 *fb0=NULL;   // framebuffer pointer
int fdFB=0;    // fb0 file descriptor
u32 fs=0;     // fb0 stride
u32 MX=0;    // xres (visible)
u32 MY=0;   // yres (visible)
u8 blk=0;  // black
u8 wht=0; // white
u8 pb=0; // pixel bits
#define bwidth 2 // width of block

void simplePixelDemo(void) {
    int x,y,tn;
    int c=0;
    struct fb_var_screeninfo screeninfo;
    fdFB=open("/dev/fb0",O_RDWR); // eink framebuffer

    // calculate model-specific vars
    ioctl(fdFB,FBIOGET_VSCREENINFO,&screeninfo);
    MX=screeninfo.xres/bwidth;  // max X+1
    MY=screeninfo.yres; // max Y+1
    pb=screeninfo.bits_per_pixel;     // pixel bits
    fs=screeninfo.xres_virtual*pb/8; // fb0 stride
    blk=pb/8-1; // black
    wht=~blk;  // white
    fb0=(u8 *)mmap(0,MY*fs,PROT_READ|PROT_WRITE,MAP_SHARED,fdFB,0); // map fb0
    eupdate(EUPD_OPEN); // open fb0 update proc
    
	MY=MY/bwidth;
    
	system("eips -c"); //clear screen

    int currentX = MX/2, currentY =MY/2; //initial point is the center of the screen
    int choice;
    int direction = 0; //the direction: 0 = right, 1 = up, 2 = left, 3 = down
    long int i;
    int cu;
    int pixels[3][LENGTH];

    for (i=0; i<LENGTH; i++) {//fill with central pixels
        pixels[0][i] = currentX;
        pixels[1][i] = currentY;
		pixels[2][i] = c++;  c&=0x3F;
    }

    srand ( time(NULL) );

    for (cu=0; cu<100; cu++) {
        tn=mpu+getmsec();

        for (i=0; i<LENGTH - STEP; i++) {
            if (i<STEP)
                setbx(pixels[0][i], pixels[1][i], 64); //clear some pixels
            // move pixels array to the left
            pixels[0][i] = pixels[0][i + STEP];
            pixels[1][i] = pixels[1][i + STEP];
            pixels[2][i] = pixels[2][i + STEP];
        }

        for (i=0; i<STEP; i++) {
            //create some new pixels
            choice = rand()%5;
            if (choice == 0) {
                direction += 1;
                direction %= 4;
            } else if (choice == 1) {
                direction -= 1;
                direction += 4;
                direction %= 4;
            } else {
                switch(direction) {
                case 0:
                    if (currentX>=MX)
                        break;
                    currentX++;
                    break;
                case 1:
                    if (currentY>=MY)
                        break;
                    currentY++;
                    break;
                case 2:
                    if (currentX<=0)
                        break;
                    currentX--;
                    break;
                case 3:
                    if (currentY<=0)
                        break;
                    currentY--;
                    break;
                }
            }

            pixels[0][LENGTH - STEP + i] = currentX;
            pixels[1][LENGTH - STEP + i] = currentY;
			pixels[2][LENGTH - STEP + i] = c++; c&=0x3F;
        }

        for (i=0; i<LENGTH; i++) {
            //display pixels
            setbx(pixels[0][i], pixels[1][i], pixels[2][i]);
        }

        eupdate(EUPD_UPDATE); // update display
        while (tn>getmsec()); // wait until next update time
    }

    // cleanup - close and free resources
    eupdate(EUPD_UPDATE);    // update display
    eupdate(EUPD_CLOSE);    // close fb0 update proc port
    munmap(fb0,fs*(MY+1)); // unmap fb0
    close(fdFB);          // close fb0
}

//===============================
// eupdate - eink update display
// op (open, close, update)
//-------------------------------
int eupdate(int op) {
    static int fdUpdate=-1;
    if (EUPD_OPEN==op) {
        fdUpdate=open("/proc/eink_fb/update_display",O_WRONLY);
    } else if (EUPD_CLOSE==op) {
        close(fdUpdate);
    } else if (EUPD_UPDATE==op) {
        if (-1==fdUpdate) {
            system("eips ''");
        } else {
            write(fdUpdate,"1\n",2);
        }
    } else {
        return -1;    // bad op code
    }
    return fdUpdate;
}

void setbx(int x, int y, int c) {
    int i,j,xx,yy;
	xx=x*bwidth;
	yy=y*bwidth;
    for (i=0; i < bwidth; i++)
	  for (j=0; j < bwidth; j++)
	    setpx (xx+i,yy+j,c);
}


//========================================
// setpx - draw pixel using ordered dither
// x,y: screen coordinates, c: color(0-64).
// (This works on all eink kindle models.)
//----------------------------------------
inline void setpx(int x,int y,int c) {
    static int dt[64] = {
        1, 33,  9, 41,  3, 35, 11, 43,
        49, 17, 57, 25, 51, 19, 59, 27,
        13, 45,  5, 37, 15, 47,  7, 39,
        61, 29, 53, 21, 63, 31, 55, 23,
        4, 36, 12, 44,  2, 34, 10, 42,
        52, 20, 60, 28, 50, 18, 58, 26,
        16, 48,  8, 40, 14, 46,  6, 38,
        64, 32, 56, 24, 62, 30, 54, 22
    }; // dither table

    fb0[pb*x/8+fs*y] = ((128&(c-dt[(7&x)+8*(7&y)]))/128*(blk&(240*(1&~x)|
                        15*(1&x)|fb0[pb*x/8+fs*y])))|((128&(dt[(7&x)+8*(7&y)]-c))/128*wht|
                                (blk&((240*(1&x)|15*(1&~x))&fb0[pb*x/8+fs*y]))); // geekmaster formula 42
}

//====================================
// getmsec - get msec since first call
// (tick counter wraps every 12 days)
//------------------------------------
int getmsec(void) {
    int tc;
    static int ts=0;
    struct timeval tv;
    gettimeofday(&tv,NULL);
    tc=tv.tv_usec/1000+1000*(0xFFFFF&tv.tv_sec);
    if (0==tc) {
        ts=tc;
    }
    return tc-ts;
}

//==================
// main - start here
//------------------
int main(int argc,char **argv) {
    if (argc>1) {
        mpu=atoi(argv[1]);
    }
    simplePixelDemo();
    return 0;
}

Last edited by jmseight; 04-21-2012 at 12:54 PM.
jmseight is offline   Reply With Quote