http://hi.baidu.com/pengsor/blog/item/460b2a030cc8089ed53f7cff.html
/*********************************************************************************
* fine name :jumpball.c
* description : jumpball in framebuffer , linux OS.
* author : hiland email: pengsor@gmail(dot)com
* license : GPL
********************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "fb_draw.h"
#include <termios.h>
#include <unistd.h>
#define r 15
#define SIDEWIDTH 1*r
#define SIDELENTH 6*r
#define CUTECOLOR 0xFF
#define BSTEP 40
int scw,sch,scw_s,sch_s,ibgcolor,iballcolor,itailcolor=0x1F;
int xstep=1,ystep=1;
void refreshscreen(int x,int y,int width,int height,int color);
void jumpball(int direct,int ir,int x,int y);
void draw_circle(int x,int y,int ir,int color);
void draw_ball(int x,int y,int w,int h,int icolor);
void waittime(long a);
int changeballcolor(int ic);
void changebgcolor(void);
void draw_movingball(int x1,int y1,int tx,int ty,int ir,int ballcolor,int bgcolor);
void draw_cute(int x,int y,int w,int h,int icolor);
void draw_movingcute(int t,int x,int y,int w,int h,int color1,int color2);
void draw_movingqute(int x,int y,int x2,int w,int h,int color1,int color2);
int main(void)
{
int x, y;
int i=0,j=0,drect=0;
int ret;
int tx,ty;
int a1,a2;
char a[32];
int tmpx,tmpy;
int toz=0;
int xb1 = 0,xb2 = 0;
char c;
struct termios old, new;
ibgcolor=0x02;
iballcolor=0xFE;
/// keyboard event setting
tcgetattr(0, &old);
tcgetattr(0, &new);
new.c_lflag &= ~(ICANON | ECHO);
new.c_cc[VMIN] = 0;
new.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new);
// tcsetattr(0, TCSANOW, &old);
//--- key board
ret=fb_open();
if(ret!=0){
fprintf(stderr,"fb_open() error./n");
exit(1);
}
scw=xres();
sch=yres();
if(scw==800) sch=600;
else {scw=800;sch=600;}
scw_s=scw-SIDELENTH;
sch_s=sch-SIDEWIDTH;
srand(getpid());
a2=rand()%10000;
a2 = 1000; // 2010-07-29
if(a2<2500) a1=0 ;
else if(a2<5000) a1=1;
else if(a2<7500) a1=2;
else if(a2<10000) a1=3;
if(a1 == 0) {tx = -1,ty = 1;}
else if(a1 == 1){tx = -1,ty = -1;}
else if(a1 == 2){tx = 1,ty = -1;}
else if(a1 == 3){tx = 1,ty = 1;}
x=(a1 + 1) * 200 - 43;
y=(a1 + 1) * 150 - 67;
refreshscreen(0,0,scw,sch,ibgcolor);
draw_circle(x,y,r,iballcolor);
draw_cute(0,sch_s,SIDELENTH ,SIDEWIDTH,CUTECOLOR);
while(1)
{
if(x>=r&&x<=scw-r)
{
if(tx == -1) x+=xstep;
else if(tx == 1) x-=xstep;
}
if(y >= r&&y <= sch_s-r)
{
if(ty == -1) y+=ystep;
else if(ty == 1) y-=ystep;
}
if(y >= sch_s-r-ystep)
iballcolor=changeballcolor(iballcolor);
draw_movingball(x,y,tx,ty,r,iballcolor,ibgcolor);
/*if(y>400){ --auto move bottom board .
if(toz == 0) {
draw_movingqute(x-3*r,sch_s,tmpx,SIDELENTH,SIDEWIDTH,CUTECOLOR,ibgcolor);
toz = 1;
}
draw_movingcute(tx,x-3*r,sch_s,SIDELENTH,SIDEWIDTH,CUTECOLOR,ibgcolor);
}
else {
if(toz == 1)
tmpx = x-3*r;
toz=0;
// tmpy = y;
}
*/
//--------------------
c = getchar();
if(c=='a'&& xb1>0)
xb2 = xb1-BSTEP > 0 ? xb1-BSTEP : 0;
else if(c=='d' && xb1<scw-SIDELENTH)
xb2= (xb1+BSTEP>scw-SIDELENTH) ? scw-SIDELENTH:xb1+BSTEP;
else if(c=='q') break;
fflush(NULL);
if(xb1 != xb2){
draw_movingqute(xb1,sch_s,xb2,SIDELENTH,SIDEWIDTH,ibgcolor,CUTECOLOR);
xb1 = xb2;
}
//-------------------
if(x >= scw - r -xstep){
tx=1;
}
else if(x <= r + xstep) {
tx=-1;
}
if(y >= sch_s - r - ystep ){
if((x > xb1 && x-xb1<SIDELENTH) || (xb1 > x && xb1-x<r)) ty=1;
else break;
}
else if(y <= r + ystep) {
ty=-1;
}
waittime(10);
}
tcsetattr(0, TCSANOW, &old);
fb_close();
return 0;
}
void draw_circle(int x,int y,int ir,int color)
{
int i,j;
int x1,y1,iwd,ihi;
x1=x-r;
y1=y-r;
if(x1<0) x1=0;
if(y1<0) y1=0;
iwd=x+ir;
ihi=y+ir;
if(iwd>scw) iwd=scw;
if(ihi>sch) ihi=sch;
for(i=x1;i<iwd;i++)
for(j=y1;j<ihi;j++)
{
if((j-y)*(j-y)<ir*ir-(i-x)*(i-x))
fb_draw_point(i,j,color);
}
}
void draw_movingball(int x1,int y1,int tx,int ty,int ir,int ballcolor,int bgcolor)
{
int i,j;
for(i=x1-ir;i<=x1+ir;i++)
for(j=y1-ir;j<=y1+ir;j++) {
if((i-x1)*(i-x1)+(j-y1)*(j-y1)<ir*ir&&(i-x1-tx*xstep)*(i-x1-tx*xstep)+(j-y1-ty*ystep)*(j-y1-ty*ystep)>=ir*ir)
fb_draw_point(i,j,ballcolor);
if((i-x1)*(i-x1)+(j-y1)*(j-y1)>=ir*ir&&(i-x1-tx*xstep)*(i-x1-tx*xstep)+(j-y1-ty*ystep)*(j-y1-ty*ystep)<=ir*ir)
fb_draw_point(i,j,bgcolor);
}
}
void draw_cute(int x,int y,int w,int h,int icolor)
{
//printf("%d,%d,%d,%d,%d",x,y,w,h,icolor);
int i,j;
int iw,ih;
int x1,y1;
x1=x;
y1=y;
if(x<0) x1=0;
if(y<0) y1=0;
if(x>scw-w) x1=scw-w;
iw=x1+w;
ih=y1+h;
if(iw > scw) iw = scw;
if(ih > sch) ih = sch;
for(i=x1;i<=iw;i++)
for(j=y1;j<=ih;j++)
fb_draw_point(i,j,icolor);
}
void draw_movingcute(int t,int x,int y,int w,int h,int color1,int color2)
{
int i,j;
int iw,ih;
int x1,y1;
int tmp;
x1=x;
y1=y;
if(x<0) x1=0;
if(y<0) y1=0;
if(x>scw-w) x1=scw-w;
iw=x1+w;
ih=y1+h;
if(iw >scw ) iw =scw;
if(ih>sch) ih=sch;
if(x<=scw-w&&x>=0) {
if(t==-1){ tmp=color1;color1=color2;color2=tmp;}
for(j=y;j<=sch;j++) {
fb_draw_point(x1,j,color1);
fb_draw_point(iw,j,color2);
}
}
}
void draw_movingqute(int x,int y,int x1,int w,int h,int color1,int color2)
{
int i,j;
int tx,ty;
int tmp=0;
tx=x;
ty=y;
if(x1 < 0) x1 = 0;
if(x < 0) tx = 0;
if(y < 0) ty = 0;
if(x1 > x)
{
for(i=x1;i>=tx;i--)
{
for(j=ty;j<=sch;j++)
{
fb_draw_point(i,j,color1);
fb_draw_point(i+w,j,color2);
// waittime(2);
}
waittime(4);
}
}
if(x1 < x)
{
for(i=x1;i<=tx;i++)
{ for(j=ty;j<=sch;j++)
{
fb_draw_point(i+w,j,color1);
fb_draw_point(i,j,color2);
// waittime(2);
}
waittime(4);
}
}
}
void refreshscreen(int x,int y,int width,int height,int icolor)
{
int i,j;
int x1,y1,iwd,ihi;
x1=x;
y1=y;
if(x1+width<=scw && y1+height<=sch)
for(i=x1;i<=x1+width;i++)
for(j=y1;j<=y1+height;j++)
fb_draw_point(i,j,icolor);
}
void waittime(long a)
{ long i,j,k;
long temp;
for(i=0;i<a*10;i++)
for(j=0;j<a*10;j++)
for(k=0;k<a*10;k++)
temp=k;
}
int changeballcolor(int ic)
{
if( ic < 0xF0) ic++;
else ic=0x80;
return ic;
}
void changebgcolor(void)
{
if (ibgcolor <0x01) ibgcolor=0x71;
else if(ibgcolor <= 0x71) ibgcolor--;
}
void drawtail(int x,int y,int icolor)
{
int x1,y1;
x1=x;
y1=y;
if(!(x1<r||y1<r||x1>scw-r||y1>sch-r))
fb_draw_point(x1,y1,icolor);
}
/*
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
strucyyt termios old, new;
char c;
tcgetattr(0, &old);
tcgetattr(0, &new);
new.c_lflag &= ~(ICANON | ECHO);
new.c_cc[VMIN] = 1;
new.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new);
while (1) {
c = getchar();
printf("%x ", c);
fflush(NULL);
if (c == 'q') {
break;
}
}
tcsetattr(0, TCSANOW, &old);
return 0;
}
*/
/*********************************************************************************
* fine name fb_draw.h
* description :
* author : hiland email: pengsor@gmail(dot)com
* license : GPL
********************************************************************************
#ifndef HS_FB_DRAW_H
#define HS_FB_DRAW_H
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/fb.h>
#if 0
struct fb_st {
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
unsigned long bpp;
int fd;
char *fbp;
};
#endif
int fb_open(void);
void fb_close(void);
void fb_draw_point(int x, int y, int color);
int xres(void);
int yres(void);
#endif
/*********************************************************************************
* fine name fb_draw.c
* description :
* author : hiland email: pengsor@gmail(dot)com
* license : GPL
********************************************************************************
#include "fb_draw.h"
#if 1
struct fb_st {
struct fb_fix_screeninfo fix;
struct fb_var_screeninfo var;
unsigned long bpp;
int fd;
char *fbp;
};
#endif
static struct fb_st fb0;
int fb_open(void)
{
int ret;
if (-1 == fb0.fd) {
perror("open");
goto error;
}
/* get fb_var_screeninfo */
ret = ioctl(fb0.fd, FBIOGET_VSCREENINFO, &fb0.var);
if (-1 == ret) {
perror("ioctl(fb0.var)");
goto close_fd;
}
fb0.bpp = fb0.var.bits_per_pixel / 8;
/* get fb_fix_screeninfo */
ioctl(fb0.fd, FBIOGET_FSCREENINFO, &fb0.fix);
if (-1 == ret) {
perror("ioctl(fb0.fix)");
goto close_fd;
}
/* get framebuffer start address */
fb0.fbp = mmap(NULL, fb0.fix.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb0.fd, 0);
if ((void *)-1 == fb0.fbp) {
perror("mmap");
goto close_fd;
}
return 0;
close_fd:
close(fb0.fd);
error:
return -1;
}
void fb_close()
{
munmap(fb0.fbp, fb0.fix.smem_len);
close(fb0.fd);
}
void fb_draw_point(int x, int y, int color)
{
unsigned long offet;
offet = fb0.bpp * (x + y * fb0.var.xres);
memset(fb0.fbp + offet, color, fb0.bpp);
}
int xres(void)
{
return fb0.var.xres;
}
int yres(void)
{
return fb0.var.yres;
}