目录
6818输入设备
输入设备
输入设备在头文件中定义的结构体
练习:获取手指触摸的指标,并且触摸后切换图片
操作一个触摸屏
五子棋游戏开发
实现功能
实现代码
main.c
pm.h
pm.c
ev.h
ev.c
正文
6818输入设备
输入设备
输入设备在头文件中定义的结构体
键盘、鼠标、触摸屏、麦克风.....
Linux下面这些输入设备也是一个文件,都包含一个头文件 #include <linux/input.h>
在头文件中定义了一个结构体
struct input_event
{
struct timeval time;//输入时间产生的时间
__u16 type;//输入事件的类型
#define EV_SYN 0x00 同步事件,用来同步数据
#define EV_KEY 0x01 按键事件,如键盘,触摸屏的接触与离开
#define EV_REL 0x02 相对事件,如鼠标的移动
#define EV_ABS 0x03 绝对事件,如触摸屏的坐标
__u16 code;//编码,为了区分同一事件类型下,不同的输入事件
#define BTN_TOUCH 0x14a(330) 接触触摸屏或者离开触摸屏
#define ABS_X 0x00 触摸屏坐标的X轴
#define ABS_Y 0x01 触摸屏的Y轴
#define ABS_PRESSURE 0x18 触摸屏的压力值事件
__s32 value;//值,根据type,code的不同,有不同的含义
如:type = 按键类型
code = BTN_TOUCH
value = 按键的状态
type = EV_ABS
code = ABS_X
value = x坐标
}
练习:获取手指触摸的指标,并且触摸后切换图片
/* 获取触摸点的位置 判断触摸动作(点击,右滑等) */ int Get_ev(int *x,int *y) { int fd = open("/dev/input/event0",O_RDONLY); if(-1 == fd) { perror("open error"); return -1; } struct input_event ev; int x1,y1; while(1) { read(fd,&ev,sizeof(ev)); printf("ev_type = %d code = %d value = %d\n",ev.type,ev.code,ev.value); if(ev.type == EV_ABS) //输入事件的类型为绝对事件,如触摸屏的坐标 { if(ev.code == 0) //触摸屏坐标的X轴 { x1 = ev.value;//6818开发板如果是黑底,x1 = ev.value * 800 / 1024。我这里是蓝底的 } else //触摸屏坐标的X轴 { y1 = ev.value ;//6818开发板如果是黑底y1 = ev.value * 480 / 600 } } if(ev.type == EV_KEY && ev.code == 330 && ev.value == 1)//保存初始坐标 { *x = x1; *y = y1; } if(ev.type == EV_KEY && ev.code == 330 && ev.value == 0) { if(*x == x1 && *y == y1) //点击 { printf("dianji\n"); } if(x1 >= *x) //右滑 { printf("zouhua\n"); } break; } } }
//写入BMP格式的图片 int Dis_pic(char *pic) { int fd = open(pic,O_RDONLY); if(-1 == fd) { perror("open error"); return -1; } int width,heigh; short depth; lseek(fd,0x12,SEEK_SET); read(fd,&width,4); read(fd,&heigh,4); lseek(fd,0x1c,SEEK_SET); read(fd,&depth,2); printf(" %d %d %d\n",width,heigh,depth); int laizi =(4 - (width * depth / 8) % 4) % 4;//要加的点 unsigned char color_buf[heigh * (width * depth / 8 + laizi)];//32 24 char color_a = 0,color_r,color_g,color_b; //颜色分量 unsigned int color;//像素点的颜色 unsigned char *p = color_buf; lseek(fd,0x36,SEEK_SET); for(int i = heigh - 1;i >= 0;i--) { for(int j = 0;j < width;j++) { color_b = *p++;//b颜色 color_g = *p++; color_r = *p++; if(32 == depth) { color_a = *p++; } // 0000 0000 0000 0000 0000 0000 1111 1111 // 0000 0000 0000 0000 1111 1111 0000 0000 //color 1111 1111 1111 1111 1111 1111 1111 1111 color = color_a << 24 | color_r << 16 | color_g << 8 | color_b;//屏幕需要的颜色a r g b Display(color, j, i); } p += laizi; } }
操作一个触摸屏
打开触摸屏文件(/dev/input/event0)
创建一个结构体,保存数据
循环读取触摸屏的数据
关闭文件
运行上述代码后,点击屏幕会返回以下运行日志
ev_type = 3 code = 0 value = 561 ev_type = 3 code = 1 value = 333 (561,333)//最开始坐标 ev_type = 1 code = 330 value = 1//第一次接触触摸屏 ev_type = 0 code = 0 value = 0 ev_type = 1 code = 330 value = 0//离开触摸屏 ev_type = 0 code = 0 value = 0
五子棋游戏开发
实现功能
有游戏开始界面,点击后进入游戏界面,判断五子连珠后弹出游戏结束界面(有部分冗余代码是做其他测试用的)
mian.c //主函数,初始化输入设备,运行 游戏函数
pm.c //画棋盘以及白字黑字的落子,还有图片写入等屏幕写入函数
ev.c //落子的具体坐标,判断五子连珠
实现代码
main.c
#include "pm.h" #include "ev.h" #include <stdio.h> int main() { int x,y; Lcd_Init(); Dis_pic("kaishi.bmp"); //写入游戏开始界面 Get_ev(&x,&y); return 0; }
pm.h
#ifndef __LCD_H__ #define __LCD_H__ #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> #include <math.h> void se(); int Lcd_Init(); void Dis_wh(); void Display( int color,int x,int y); int Dis_pic(char *pic); void Dis_pan(); void Dis_xian(); void Dis_baizi(int x,int y); void Dis_heizi(int x,int y); #endif
pm.c
#include <stdio.h> #include "pm.h" unsigned int *plcd =NULL; void Display( int color,int x,int y) { if(x >= 0 && x <=800 && y >= 0 && y <= 480){ *(plcd + y * 800 + x) = color; } } void se() { int fd = open("/dev/fb0",O_RDWR); if(fd == -1) { perror("open error"); } int color[10] = {0x10900,0xff00ff,0xf0394f,0xf009ba9f,0xf066f3,0x856fa,0x9392c83b}; int j=0; while(1){ for(int i=0;i<384000;i++){ int w = write(fd,&color[j],4); if(-1 == w) { perror("write error"); } } sleep(2); j++; if(j==7) j=0; lseek(fd,0,SEEK_SET);//定位光标在文件头 } } int Lcd_Init() { int fd = open("/dev/fb0",O_RDWR); if(fd == -1){ perror("open error"); return -2; } plcd = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0); } void Dis_wh() { //int color[10] = {0x190f0,0xff00ff,0xff,0xff0000ff,0xf0f083,0x8596fa,0x298c83b}; //int q=0; //while(1){ for (int i = 0;i <= 880;i++){ for(int j = 0;j < 480;j++){ //int p = if(((i-400)*(i-400) + (j-240)*(j-240) - 1)*((i-400)*(i-400) + (j-240)*(j-240) - 1)*((i-400)*(i-400) + (j-240)*(j-240) - 1)< (i-400)*(i-400) - (j-240)*(j-240)){ Display(0xf0f083, i, j); } } //} //sleep(2); //q++; //if(q==7) q=0; } } //画图片 int Dis_pic(char *pic) { int fd = open(pic,O_RDONLY); if(-1 == fd) { perror("open error"); return -1; } int width,heigh; short depth; lseek(fd,0x12,SEEK_SET); read(fd,&width,4); read(fd,&heigh,4); lseek(fd,0x1c,SEEK_SET); read(fd,&depth,2); printf(" %d %d %d\n",width,heigh,depth); int laizi; unsigned char color_buf[width * heigh * depth / 8];//32 24 char color_a = 0,color_r,color_g,color_b; //颜色分量 unsigned int color;//像素点的颜色 char *p = color_buf; lseek(fd,0x36,SEEK_SET); read(fd,color_buf,width * heigh * depth / 8); for(int i = heigh - 1;i >= 0;i--) { for(int j = 0;j < width;j++) { color_b = *p++;//b颜色 color_g = *p++; color_r = *p++; if(32 == depth) { color_a = *p++; } color = color_a << 24 | color_r << 16 | color_g << 8 | color_b;//屏幕需要的颜色a r g b Display(color, j, i); } } } void Dis_pan() { for(int i = 0;i < 800;i++){ for(int j = 0;j < 480;j++){ Display(0xf0f00f, i, j); } } } void Dis_xian() { for(int i = 50;i <= 650;i+=50){ for(int j = 20;j < 460;j++){ Display(0x0, i, j); } } for(int i = 20;i <= 460;i+=40){ for(int j = 50;j < 650;j++){ Display(0x0, j, i); } } } void Dis_baizi(int x,int y) { for(int i = 0;i < 480;i++){ for(int j = 0;j < 800;j++){ if((i-x)*(i-x) + (j-y)*(j-y)<170) { Display(0xffffff, j, i); } } } } void Dis_heizi(int x,int y) { for(int i = 0;i < 480;i++){ for(int j = 0;j < 800;j++){ if((i-x)*(i-x) + (j-y)*(j-y)<170) { Display(0x0, j, i); } } } }
ev.h
#ifndef __EV_H__ #define __EV_H__ #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> #include <math.h> #include <linux/input.h> int Get_ev(int *x,int *y); int jud(int a,int b,int c); #endif
ev.c
#include "ev.h" #include "pm.h" int state[12][13]={0}; int jud(int a,int b,int c) { int num=0; if(state[a][b]==c) { for(int i=0;i <= 12;i++) //判断横 { if(state[a][i]==c) { num++; if(num == 5) { Dis_pic("t5.bmp"); return 2; break; } } else num=0; } for(int i=0;i <= a+4;i++) //判断竖 { if(state[i][b]==c) { num++; if(num == 5) { Dis_pic("t5.bmp"); return 2; break; } } else num=0; } if(a<=b) //判断左上到右下 { for(int i=0,j=b-a;i<12 && j<13;i++,j++) { if(state[i][j]==c) { num++; if(num == 5) { Dis_pic("t5.bmp"); return 2; break; } } else num=0; } } else if(a>b) //判断左上到右下 { for(int j=0,i=a-b;i<12 && j<13;i++,j++) { if(state[i][j]==c) { num++; if(num == 5) { Dis_pic("t5.bmp"); return 2; break; } } else num=0; } } if(a>=b) //判断右上到左下 { for(int i=a+b,j=0;i>=0;i--,j++) { if(state[i][j]==c) { num++; if(num == 5) { Dis_pic("t5.bmp"); return 2; break; } } else num=0; } } if(b>a) //判断右上到左下 { for(int i=11,j=b+a-11;j<=12;i--,j++) { if(state[i][j]==c) { num++; if(num == 5) { Dis_pic("t5.bmp"); return 2; break; } } else num=0; } } } } int Get_ev(int *x,int *y) { int fd = open("/dev/input/event0",O_RDONLY); if(-1 == fd) { perror("open error"); return -1; } struct input_event ev; int x1,y1,q=0,w; while(1) { read(fd,&ev,sizeof(ev)); printf("ev_type = %d code = %d value = %d\n",ev.type,ev.code,ev.value); if(ev.type == EV_ABS) { if(ev.code == 0)//x { x1 = ev.value; } else { y1 = ev.value; } } if(ev.type == EV_KEY && ev.code == 330 && ev.value == 1)//保存初始坐标 { *x = x1; *y = y1; } //点击 if(ev.type == EV_KEY && ev.code == 330 && ev.value == 0) { if(*x == x1 && *y == y1)//点击 { printf("dianji\n"); Dis_pan(); Dis_xian(); break; } } } while(1) { read(fd,&ev,sizeof(ev)); printf("ev_type = %d code = %d value = %d\n",ev.type,ev.code,ev.value); if(ev.type == EV_ABS) { if(ev.code == 0)//x { x1 = ev.value;// 1024 } else { y1 = ev.value; } } if(ev.type == EV_KEY && ev.code == 330 && ev.value == 1)//保存初始坐标 { *x = x1; *y = y1; } //点击 if(ev.type == EV_KEY && ev.code == 330 && ev.value == 0) { if(*x == x1 && *y == y1)//点击 { printf("dianji\n"); for(int i = 20;i <= 460;i+=40) { for(int j = 50;j <= 650;j+=50) { int a,b; a=(i-20)/40; b=(j-50)/50; if(q == 0 && (*x - j)*(*x - j) + (*y - i)*(*y - i) < 400 && state[a][b] == 0) { Dis_heizi(i, j); state[a][b]=1; printf("%d--%d--%d",a,b,state[a][b]); w = jud(a,b,1); q++; break; } else if(q == 1 && (*x - j)*(*x - j) + (*y - i)*(*y - i) < 400 && state[a][b] == 0) { Dis_baizi(i, j); state[a][b]=2; w = jud(a,b,2); q--; break; } } if(w == 2) break; } } } } }