Zealot
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.
|