Carpe diem, c'est la vie.
Posts: 6,433
Karma: 10773670
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
|
palpump - geekmaster palette pump demo
Spoiler:
PHP Code:
//==================================================== // palpump 1.0 - kindle palette pump demo // Copyright (C) 2012 by geekmaster, 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,K4(Mini),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
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); int eupdate(int); int getmsec(void); void palette(int);
// global var7 u32 mpu=100; // 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
//=============================================== // palpump - kindle palette pump demo // This works on all kindle eink models. Enjoy! //----------------------------------------------- void cosmegg(void) { int x,y,c,tn,i,j; 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; // 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
system("eips 17 32 'Palette Pump 1.0'"); system("eips 19 34 'by Geekmaster'");
for (j=MX-32;j>80;j-=24) { for(i=j;i>8;i-=8) { tn=mpu+getmsec(); palette(i); eupdate(EUPD_UPDATE); // update display while (tn>getmsec()); // wait until next update time } for(i=8;i<j;i+=8) { tn=mpu+getmsec(); palette(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 }
//========================================= // palette - display scaled "color" palette //----------------------------------------- void palette(int s) { int x,y; for (y=(MX-s)/2;y<(MX+s)/2;y++) for (x=(MX-s)/2;x<(MX+s)/2;x++) { setpx(x,y,(y-(MX-s)/2)*8/s*8+(x-(MX-s)/2)*8/s); } }
//=============================== // 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; }
//======================================== // 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] = { 0,32,8,40,2,34,10,42,48,16,56,24,50,18,58,26,12,44,4, 36,14,46,6,38,60,28,52,20,62,30,54,22,3,35,11,45,1,33,9,41,51,19,59,27,49, 17,57,25,15,47,7,39,13,45,5,37,63,31,55,23,61,29,53,21 }; // 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]); } cosmegg(); // do the cosmic egg demo :D return 0; }
This started as a test stub to verify the "color palette" dither table values. I now subtracted one from all values so it can get a pure black. Remember that dithering with an 8x8 table gives 65 shades, not 64 as 6-bit colors would give. Anyway, this is an animated "color" palette demo. Not as flashy as the others, but it shows how to use a new function (scaleable palette display). I animate the scaling factor here.
Using this new color palette in some existing programs can make the WHITE value go away, requiring adjustment to the color scale factors in the program.
Remember to clear the screen (eips -c) before running this each time.
The moving palette "wall" appears to be semi-transparent, but that "transparency" is just eink ghosting, which you would not see in a screenshot, but that ghosting looks interesting and contributes to the effect in this demo.
Last edited by geekmaster; 04-19-2012 at 05:23 AM.
|