粤嵌GEC6818,基于LVGL和mplayer的音视频播放器

Posted 旧金山路人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了粤嵌GEC6818,基于LVGL和mplayer的音视频播放器相关的知识,希望对你有一定的参考价值。

#include <myplay.h>

pthread_mutex_t mutex_lv;//lvgl线程锁

static char local_music_path[]="/tmp/newwork/8.30big_project/music";//音乐路径

static char local_pic_path[]="/tmp/newwork/photo";//图片路径

static char local_words_path[]="/tmp/newwork/words";//歌词路径

static char local_video_path[]="/tmp/newwork/tv";//视频路径

static char music_path[100][1024];//音乐路径

static char pic_path[100][1024];//图片路径

static char words_path[100][1024];//歌词路径

static char video_path[100][1024];//视频路径

static char words_buf[5*1024]=0;//放歌词的数组

static FILE *fp_mplayer=NULL;   //播放器传回的管道,接收播放进度

static FILE *fp_words=NULL;     //歌词文件

static int fd_mplayer = 0;      //定义管道文件描述符,发送指令给mplayer

static int music_num=0;         //音乐数量

static int music_index=-1;      //当前音乐的下标值,用于寻找上下首

static int video_index=-1;      //当前视频的下标值,用于寻找上下首

static int video_num=0;         //视频的数量

static int percent_pos;         //当前播放百分比

static float time_length;       //歌曲长度

static float time_pos;          //当前播放进度

static bool list_flag=1;    //开关列表

static bool words_flag=1;    //歌词列表

static bool play_flag=0;    //播放音乐开关

static bool start=0;        //启动,线程读mplayer返回信息

static lv_style_t font_style;   //中文

static lv_obj_t *play_mode;     //下拉列表对象,播放模式

static lv_obj_t *speed_obj;     //下拉列表对象,播放速度

static lv_obj_t * music_list;   //音乐列表对象

static lv_obj_t *pic_obj;       //图片对象

static lv_obj_t * volume_slider;  //音量滑条对象

static lv_obj_t * play_slider;  //播放进度条对象

static lv_obj_t * cont;         //音乐盒的背景对象

static lv_obj_t * video_list;   //视频列表对象

static lv_obj_t *title_label;     //图片信息标签

static lv_obj_t *words_label;     //歌词标签

static lv_obj_t * volume_label; //音量标签

static lv_obj_t *time_length_label; //时长标签

static lv_obj_t *time_pos_label; //当前时间标签

static lv_obj_t *words_list;     //歌词标签  

pthread_cond_t cond;        //条件变量,用于暂停读取mplayer

pthread_cond_t cond1;

pthread_mutex_t mutex;

pthread_mutex_t mutex1;

pthread_t tid_read;         //读mplayer的线程id

pthread_t tid_write;        //写mplayer的线程id

//这里为音乐播放器部分

//获取音乐的路径,检测本地歌单

void get_music_path()

    //读目录,mp3后缀保存到数组

    music_num =0;

    DIR *dirp = opendir(local_music_path);

    if(dirp==NULL)

   

        perror(local_music_path);

        exit(0);

   

    struct dirent* msg;

    while(1)

   

        msg = readdir(dirp);

        if(msg == NULL)break;

        if(msg->d_name[0]=='.')continue;

        if(strstr(msg->d_name,".mp3"))

       

            sprintf(music_path[music_num], "%s/%s", local_music_path, msg->d_name);

            //拼接图片与歌词路径↓

            char name[100]=0;

            strcpy(name,strtok(msg->d_name,"."));

            sprintf(pic_path[music_num], "S:%s/%s.png", local_pic_path, name);

            sprintf(words_path[music_num], "%s/%s.txt", local_words_path, name);

            //拼接图片与歌词路径↑

            music_num++;

            puts(music_path[music_num - 1]);

            puts(pic_path[music_num - 1]);

            puts(words_path[music_num - 1]);

       

   

    printf("检索歌单完成 共%d\\n",music_num);

//初始化字体风格

void init_font_style()

    /*创建字体*/

    static lv_ft_info_t info;

    info.name = "/font/simkai.ttf";//字体位置

    info.weight = 18;//大小

    info.style = FT_FONT_STYLE_NORMAL;//风格

    info.mem = NULL;

    if(!lv_ft_font_init(&info))

        LV_LOG_ERROR("create failed.");

   

    /*给字体设置样式*/

   

    lv_style_init(&font_style);

    lv_style_set_text_font(&font_style, info.font);

    lv_style_set_text_align(&font_style, LV_TEXT_ALIGN_CENTER);

    //lv_obj_add_style(label, &style, 0);

//初始化图片的父对象,即图片都在这个对象中显示

void init_pic_parent_obj()

    //在屏幕中创建一个对象

    lv_obj_t * img = lv_obj_create(cont);

    //取消滚动

    lv_obj_clear_flag(img, LV_OBJ_FLAG_SCROLLABLE);

    lv_obj_set_size(img, 200, 200);

    lv_obj_align(img, LV_ALIGN_CENTER, 0, -60);

    // lv_obj_set_style_pad_all

    //图片对象

    pic_obj = lv_img_create(img);

    lv_obj_center(pic_obj);  

//信号任务

void signal_10_task(int arg)

    if (arg == 10)

   

        printf("收到信号 %d 线程任务(读取mplayer)暂停\\n", arg);

        pthread_kill(tid_write,12); //停止写

        pthread_cond_wait(&cond, &mutex);   //停止读

        pthread_cond_signal(&cond1);//唤醒获取时间

        puts("继续工作,读mplayer");

        return;

   

//信号任务

void signal_12_task(int arg)

    //printf("收到信号 %d\\n",arg);

    printf("收到信号 %d 线程任务(get_time_pos)暂停\\n", arg);

    pthread_cond_wait(&cond1, &mutex1);

    puts("继续工作,写mplayer");  

    return;

static char words_line[1024]=0;

//初始化歌曲信息的父对象

void init_title_obj()

    // //在屏幕中创建一个对象

   

    lv_obj_t * title = lv_obj_create(cont);

    lv_obj_clear_flag(title, LV_OBJ_FLAG_SCROLLABLE);//禁用滚动

    lv_obj_set_size(title, 200, 50);

    lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);

   

    //标题标签

    title_label = lv_label_create(title);

   


 

    //添加字体

    lv_obj_add_style(title_label, &font_style, 0);

    lv_obj_center(title_label);

    lv_label_set_text(title_label, "开启音乐之旅");

    //歌词标签

    words_label = lv_label_create(cont);

   

    lv_obj_align(words_label,LV_ALIGN_CENTER,0,70);

    lv_obj_add_style(words_label, &font_style, 0);

    lv_label_set_text(words_label,"歌词");

//找歌词

void *find_words_task(void *arg)

 

    char *p=strstr(words_buf,(char *)arg);//寻找这个时间有没有歌词

    if(p!=NULL)                 //和歌词相同时间

               

        char buf[1024]=0;

        sscanf(p,"%s",buf);

        char *q = strrchr(buf,']');

        sscanf(++q,"%s",buf);  

        if(strcmp(buf,words_line))//不相同

       

            strcpy(words_line,buf);

           

            //puts(words_line);  

            //**********歌词标签

            //lv_label_set_text(words_label,words_line);

           

            pthread_mutex_lock(&mutex_lv);//上锁

            lv_label_set_text(words_label,words_line);

            pthread_mutex_unlock(&mutex_lv);

           

   

//线程任务 读播放器返回内容

static char show_time_buf[100]=0;

void *read_mplayer_task(void *arg)

   

    //注册一个信号

    signal(10, signal_10_task);//收到10就暂停

    char line[1024]=0;                //返回信息

    char *p;

    while (1)

   

        memset(line, 0, 1024);

        fgets(line,1024,fp_mplayer);  //读取进程返回的内容

        //printf("返回 %s",line);      

        if(strstr(line,"ANS_TIME_POSITION"))//当前播放秒数

       

            p=strrchr(line,'=');

            p++;    

            sscanf(p,"%f",&time_pos);

            printf("歌曲播放时间 %.2f\\n",time_pos);

            char tmp[100]=0;

            int tmp_time=time_pos;

            sprintf(tmp,"%02d:%02d",tmp_time/60,tmp_time % 60);

            if(strcmp(show_time_buf,tmp))//不相同

           

                strcpy(show_time_buf,tmp);

                //lv_label_set_text(time_pos_label,show_time_buf); //设置标签

                pthread_mutex_lock(&mutex_lv);//上锁

                lv_label_set_text(time_pos_label,show_time_buf);

                pthread_mutex_unlock(&mutex_lv);//解锁

           

            puts(tmp);//打印时间  00:00

            //*********开启线程找歌词**********//

            pthread_t tid;

            pthread_create(&tid,NULL,find_words_task,tmp);

            pthread_detach(tid);    

            //*******************//

       

        if(strstr(line,"ANS_PERCENT_POSITION"))//播放百分比

       

             p=strrchr(line,'=');//p++;    

            int percent=0;

            sscanf(++p,"%d",&percent);

            printf("播放百分比 %d\\n",percent_pos);

             if(percent!=percent_pos)

           

            percent_pos=percent;

            //lv_slider_set_value(play_slider,percent_pos,LV_ANIM_OFF);//设置进度条值

            pthread_mutex_lock(&mutex_lv);//上锁

            lv_slider_set_value(play_slider,percent_pos,LV_ANIM_OFF);

            pthread_mutex_unlock(&mutex_lv);

           

            if(percent_pos>=99)//播完了

           

                lv_label_set_text(time_pos_label,"0:00");

                //播放模式

                int mod = lv_dropdown_get_selected(play_mode);

                switch (mod)

                   

                        case 0:

                                pthread_kill(tid_read,10);//停止读写mplayer

                                break;

                               

                        case 1://循环播放

                                break;          

                        case 2://列表循环

                               

                                if(++music_index >= music_num)music_index=0;

                                play_one_music();

                                break;

                               

                        case 3://随机播放

                               

                                srand((unsigned)time(NULL));

                                music_index = (music_index+rand())%music_num;

                                play_one_music();

                                break;

                                             

                        default:

                                break;

                   


 

           

       

        if(strstr(line,"ANS_LENGTH"))//歌曲长度

       

            p=strrchr(line,'=');p++;    

            sscanf(p,"%f",&time_length);

            printf("歌曲长度 %.2f\\n",time_length);

            char time_buf[100]=0;

            int length=time_length;

            sprintf(time_buf,"%02d:%02d",length/60,length % 60);

            puts(time_buf);

            pthread_mutex_lock(&mutex_lv);//上锁

            lv_label_set_text(time_length_label,time_buf); //设置标签

            pthread_mutex_unlock(&mutex_lv);//解锁

       

       


 

   

   

//线程任务 发送命令给mplayer

void *write_mplayer_task(void *arg)

    //注册一个信号

    signal(12, signal_12_task);//收到12就暂停

    char cmd1[1024]="get_time_pos\\n";

    char cmd[1024]="get_percent_pos\\n";

    while(1)

   

        write(fd_mplayer,cmd1,strlen(cmd1));//发送获取时间命令

        usleep(400*1000);

        write(fd_mplayer,cmd,strlen(cmd));//发送获取百分比

        usleep(400*1000);

        //sleep(1);      

   

//线程任务 创建子进程播放音乐

void *play_music_task(void *arg)

   

    printf("---- %ld线程任务------------------\\n",pthread_self());

    //拼接命令

    char cmd[1024]="mplayer -slave -quiet -input file=/pipe";

    sprintf(cmd,"%s %s",cmd,music_path[music_index]);

   

    //puts(cmd);  

    //播放音乐

    fp_mplayer = popen(cmd, "r");

    if (fp_mplayer == NULL)perror("popen fail:");

    puts("----线程任务(启动播放音乐)完成 -----------------------\\n");

    strcpy(cmd,"get_time_length\\n");    //获取长度

    write(fd_mplayer,cmd,strlen(cmd));

    strcpy(cmd,"get_time_pos\\n");    //发送获取时间命令

    write(fd_mplayer,cmd,strlen(cmd));

    pthread_exit(NULL);//线程结束

//播放一首音乐

void play_one_music()

 

    if(play_flag != 0)//看看有没有线程在使用播放器

   

        system("killall -9 mplayer");

   

    play_flag=1;

    printf("音乐索引%d\\n", music_index);

    //开启线程播放音乐

    pthread_t tid;

    int pt = pthread_create(&tid, NULL, play_music_task, NULL);

    if(pt != 0)

   

        perror("创建进程失败");

        return -1;

       

   

    pthread_detach(tid);//分离属性,自动回收

    if(!start)

   

        sleep(1);

        //读取mplayer的内容

        pthread_create(&tid_read, NULL, read_mplayer_task, NULL);//新建线程

        pthread_detach(tid_read);//分离属性,自动回收

        //发送获取时间命令

        pthread_create(&tid_write, NULL, write_mplayer_task, NULL);

        pthread_detach(tid_write);//分离属性,自动收回

        printf("tid_read %ld  tid_write %ld\\n",tid_read,tid_write);

        start=1;

   

    pthread_cond_signal(&cond);//唤醒线程读取mplayer返回的内容

    //***************************************************************//

    char tmp[100]=0;

   

    char *p = strrchr(music_path[music_index],'/');

    strcpy(tmp,++p);

   

    lv_label_set_text(title_label,strtok(tmp,"."));

    lv_label_set_text(words_label,strtok(tmp,"."));

   

    //显示音乐图片

    lv_img_set_src(pic_obj,pic_path[music_index]);

     //打开歌词文件

    FILE *fp = fopen(words_path[music_index],"r");

    memset(words_buf,0,sizeof(words_buf));

    if(fp!=NULL)

   

        fread(words_buf,5*1024,4,fp);

   

    fclose(fp);

    //设置播放属性

    int ret = lv_dropdown_get_selected(speed_obj);

    //音量

    int volume=(int)lv_slider_get_value(volume_slider);

    char cmd[1024]=0;

    sprintf(cmd,"volume %d 1\\n",volume);

    write(fd_mplayer,cmd,strlen(cmd));

    //修改播放速度

    switch (ret)

   

        case 0:

                char cmd[1024]="speed_set 1\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                break;

               

        case 1:      

                char cmd[1024]="speed_set 1.25\\n";

                write(fd_mplayer,cmd,strlen(cmd));  

                break;    

               

        case 2:      

                char cmd[1024]="speed_set 1.5\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                break;

               

        case 3:      

                char cmd[1024]="speed_set 2\\n";        

                write(fd_mplayer,cmd,strlen(cmd));        

                break;

                 

        default:        

                break;

   

    //播放模式

    int mod = lv_dropdown_get_selected(play_mode);

    switch (mod)

   

        case 0:

                char cmd[1024]="loop -1\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                break;

               

        case 1:

                char cmd[1024]="loop -1\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                strcpy(cmd,"loop 1\\n");write(fd_mplayer,cmd,strlen(cmd));        

                break;

               

        case 2://列表循环

                       

                break;    

               

        case 3://随机播放

                     

                break;

                         

        default:        

                break;

   



 

//列表处理函数,播放列表中的音乐

static lv_event_cb_t event_handler_music_list(lv_event_t * e)

    //获取事件码

    lv_event_code_t code = lv_event_get_code(e);

    //获取事件对象,这里是按钮

    lv_obj_t * obj = lv_event_get_target(e);

    //如果点击按钮

    if(code == LV_EVENT_CLICKED)

   

        //打印按钮中的文本

        //LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(music_list, obj));

        printf("Clicked  %s\\n", lv_list_get_btn_text(music_list, obj));

       

        //当前播放中的音乐下标更新为点击列表的下标

        music_index = lv_event_get_user_data(e);

        play_one_music();        

   

     

//显示歌单列表

static void show_list()

    //创建列表文本框

    music_list = lv_list_create(cont);

    //添加风格

    lv_obj_add_style(music_list, &font_style, 0);

    lv_obj_set_size(music_list, 180, 300);

    //列表位置

    //lv_obj_center(music_list);

    lv_obj_align(music_list, LV_ALIGN_RIGHT_MID, -20, -80);

    //添加文本

    lv_list_add_text(music_list, "Music list");

    /*在列表中添加按钮*/

    lv_obj_t *btn;

    for(int i = 0; i < music_num; i++)

   

        char tmp[100]=0;

        char *p = music_path[i];

        p = strrchr(p,'/');

        strcpy(tmp,++p);//裁剪到只剩音乐名字  music.mp3

        //参数:列表对象,图标宏,按钮名

        btn = lv_list_add_btn(music_list, NULL,strtok(tmp,"."));

        //列表按钮风格

        lv_obj_add_style(music_list, &font_style, 0);

        //触发事件,把下标传递

        lv_obj_add_event_cb(btn, event_handler_music_list, LV_EVENT_CLICKED, i);

   

//按钮事件

static void btn_handler(lv_event_t * e)

    lv_event_code_t code = lv_event_get_code(e);

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    if(code == LV_EVENT_CLICKED) //点击按钮

   

        if(strcmp(msg,"pause") == 0)

       

            if(!start)return;

            pthread_kill(tid_read,10);//暂停读mplayer返回内容      

            system("killall -19 mplayer");

       

        if(strcmp(msg,"play") == 0)

       

            if(!start)return;

            system("killall -18 mplayer");//播放器继续

            pthread_cond_signal(&cond);//唤醒读写mplayer

            usleep(1000);

            pthread_cond_signal(&cond);//防止被再次暂停

       

        if(strcmp(msg,"forward") == 0)

       

            if(!start)return;

            usleep(1000);

            char  cmd[1024]="seek +10\\n";

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令    

       

        if(strcmp(msg,"back") == 0)

       

            if(!start)return;

            usleep(10000);

            char  cmd[1024]="seek -10\\n";

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令  

       

        if(strcmp(msg,"next_music") == 0)

       

            usleep(1000);

            //播放模式

            int mod = lv_dropdown_get_selected(play_mode);

            switch (mod)

           

            case 1:

           

                play_one_music();break;

           

            case 0:

            case 2://列表循环

           

                if(++music_index >= music_num)music_index=0;

                play_one_music();

                break;

           

            case 3://随机播放

           

                srand((unsigned)time(NULL));

                music_index = (music_index+rand())%music_num;

                printf("music_index %d\\n",music_index);

                play_one_music();

                break;

                         

            default:

                break;

           

       

        if(strcmp(msg,"prev_music") == 0)

       

            usleep(1000);

            //播放模式

            int mod = lv_dropdown_get_selected(play_mode);

            switch (mod)

           

            case 1://循环播放

            char cmd[1024]="loop -1\\n";write(fd_mplayer,cmd,strlen(cmd));

            strcpy(cmd,"loop 1\\n");write(fd_mplayer,cmd,strlen(cmd));play_one_music();break;

            case 0://单曲

            case 2://列表循环

           

                if(--music_index <= 0)music_index=music_num-1;

                play_one_music();

                break;

           

            case 3://随机播放

           

                srand((unsigned)time(NULL));

                music_index = (music_index+rand())%music_num;

                play_one_music();

                break;

                         

            default:

                break;

           

       

        if(strcmp(msg,"show_list") == 0)

       

            list_flag=!list_flag;

            if(list_flag)

                lv_obj_clear_flag(music_list,LV_OBJ_FLAG_HIDDEN);        

            else

                lv_obj_add_flag(music_list, LV_OBJ_FLAG_HIDDEN);

       

   

//显示按钮

void show_button()

    //风格设置

    static lv_style_t btn_style;

    lv_style_init(&btn_style);

    /*Set a background color and a radius*/

    lv_style_set_radius(&btn_style,90);

    lv_style_set_bg_opa(&btn_style, LV_OPA_COVER);

    lv_style_set_bg_color(&btn_style, lv_palette_lighten(LV_PALETTE_BLUE, 1));//按钮色

    /*Add a shadow*/

    lv_style_set_shadow_width(&btn_style, 55);

    lv_style_set_shadow_color(&btn_style, lv_palette_main(LV_PALETTE_BLUE));//背景色

    //按钮的标签

    lv_obj_t *label;

    //暂停按钮

    lv_obj_t *btn_pause = lv_btn_create(cont);

    //按钮事件

    lv_obj_add_event_cb(btn_pause, btn_handler, LV_EVENT_ALL,"pause");  

    //位置

    lv_obj_align(btn_pause, LV_ALIGN_BOTTOM_MID,40,-20);

    //大小

    lv_obj_set_size(btn_pause,60,60);

    //图标

    lv_obj_set_style_bg_img_src(btn_pause,LV_SYMBOL_PAUSE,0);

    //添加风格

    lv_obj_add_style(btn_pause,&btn_style,0);

    //播放按钮

    lv_obj_t *btn_play = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_play, btn_handler, LV_EVENT_ALL,"play");  

    lv_obj_align(btn_play, LV_ALIGN_BOTTOM_MID,-40,-20);

    lv_obj_set_size(btn_play,60,60);

    lv_obj_set_style_bg_img_src(btn_play,LV_SYMBOL_PLAY,0);

    lv_obj_add_style(btn_play,&btn_style,0);

    //快进

    lv_obj_t *btn_forward = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_forward, btn_handler, LV_EVENT_ALL,"forward");

    lv_obj_set_size(btn_forward,60,60);

    lv_obj_align(btn_forward, LV_ALIGN_BOTTOM_MID,120,-20);

    lv_obj_set_style_bg_img_src(btn_forward,LV_SYMBOL_RIGHT LV_SYMBOL_RIGHT,0);

    lv_obj_add_style(btn_forward,&btn_style,0);

    //快退

    lv_obj_t *btn_back = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_back, btn_handler, LV_EVENT_ALL,"back");

    lv_obj_set_size(btn_back,60,60);

    lv_obj_align(btn_back, LV_ALIGN_BOTTOM_MID,-120,-20);

    lv_obj_set_style_bg_img_src(btn_back,LV_SYMBOL_LEFT LV_SYMBOL_LEFT,0);

    lv_obj_add_style(btn_back,&btn_style,0);

    //下一首

    lv_obj_t *btn_next = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_next, btn_handler, LV_EVENT_ALL,"next_music");

    lv_obj_set_size(btn_next,60,60);

    lv_obj_align(btn_next, LV_ALIGN_BOTTOM_MID,200,-20);

    lv_obj_set_style_bg_img_src(btn_next,LV_SYMBOL_NEXT,0);

    lv_obj_add_style(btn_next,&btn_style,0);

    //上一首

   

    lv_obj_t *btn_prev = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_prev, btn_handler, LV_EVENT_ALL,"prev_music");

    lv_obj_set_size(btn_prev,60,60);

    lv_obj_align(btn_prev, LV_ALIGN_BOTTOM_MID,-200,-20);

    lv_obj_set_style_bg_img_src(btn_prev,LV_SYMBOL_PREV,0);

    lv_obj_add_style(btn_prev,&btn_style,0);

    //显示,隐藏  歌单列表

    //风格设置

    static lv_style_t style;

    lv_style_init(&style);

    /*设置背景颜色和半径*/

    lv_style_set_radius(&style, 5);

    lv_style_set_bg_opa(&style, LV_OPA_COVER);

    lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));

    /*添加一个影子*/

    lv_style_set_shadow_width(&style, 55);

    lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE));

    //歌单列表

    lv_obj_t *btn_list = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_list, btn_handler, LV_EVENT_ALL,"show_list");

    lv_obj_set_size(btn_list,60,60);

    lv_obj_align(btn_list, LV_ALIGN_BOTTOM_RIGHT,-20,-90);

    label = lv_label_create(btn_list);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "menu");

    lv_obj_center(label);

    lv_obj_add_style(btn_list, &style, 0);

//下拉列表事件

static void dd_handler(lv_event_t * e)

    //获取事件码

    lv_event_code_t code = lv_event_get_code(e);

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);  

    if(code == LV_EVENT_VALUE_CHANGED)//值被修改

   

        if(strcmp(msg,"speed")==0)

       

            //获取事件对象

            //lv_obj_t *speed = lv_event_get_target(e);

            int ret = lv_dropdown_get_selected(speed_obj);

            //printf("ret = %d\\n",ret);

            //修改播放速度

            switch (ret)

           

            case 0:

           

                char  cmd[1024]="speed_set 1\\n";

                write(fd_mplayer,cmd,strlen(cmd));  

                break;

           

            case 1:

           

                char  cmd[1024]="speed_set 1.25\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                break;

           

            case 2:

           

                char  cmd[1024]="speed_set 1.5\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                break;

           

            case 3:

           

                char  cmd[1024]="speed_set 2\\n";

                write(fd_mplayer,cmd,strlen(cmd));

                break;

                     

            default:

                break;

           

       

        if(strcmp(msg,"play_mode")==0)

       

            //播放模式

            int mod = lv_dropdown_get_selected(play_mode);

            switch (mod)

           

            case 0:char cmd[1024]="loop -1\\n";write(fd_mplayer,cmd,strlen(cmd));break;

            case 1:

            char cmd[1024]="loop -1\\n";write(fd_mplayer,cmd,strlen(cmd));

            strcpy(cmd,"loop 1\\n");write(fd_mplayer,cmd,strlen(cmd));        break;

            case 2://列表循环

                   break;    

            case 3://随机播放

                  break;

                     

            default:        break;

           

       

   

//显示下拉列表

static void show_drop_down()

    static const char * opts = "x1\\n"

                               "x1.25\\n"

                               "x1.5\\n"

                               "x2";

    static const char * opts1 = "single\\n"

                               "circle\\n"

                               "list\\n"

                               "random";                          

    //播放速度 创建一个对象

    speed_obj = lv_dropdown_create(cont);

    //lv_dropdown_set_text(speed_obj, "Speed");

    //触发事件

    lv_obj_add_event_cb(speed_obj,dd_handler,LV_EVENT_ALL,"speed");

    //添加选项

    lv_dropdown_set_options_static(speed_obj, opts);

    //大小

    lv_obj_set_size(speed_obj,80,40);

    //位置

    lv_obj_align(speed_obj, LV_ALIGN_BOTTOM_RIGHT, -60, -20);

    //箭头位置,现在由低朝上

    lv_dropdown_set_dir(speed_obj, LV_DIR_BOTTOM);

    //列表弹出方向

    lv_dropdown_set_symbol(speed_obj, LV_SYMBOL_UP);

    //标签

    lv_obj_t *speed_label = lv_label_create(cont);

    lv_obj_add_style(speed_label, &font_style, 0);

    lv_label_set_text(speed_label, "speed");

    lv_obj_align_to(speed_label, speed_obj, LV_ALIGN_OUT_TOP_MID, 0, 0);

    //播放模式

    play_mode = lv_dropdown_create(cont);

    //添加字体

    //lv_obj_add_style(play_mode, &font_style, 0);

    lv_obj_add_event_cb(play_mode,dd_handler,LV_EVENT_ALL,"play_mode");

    lv_dropdown_set_options_static(play_mode, opts1);

    lv_obj_set_size(play_mode,100,40);

    //位置

    lv_obj_align(play_mode, LV_ALIGN_BOTTOM_LEFT, 40, -20);

    lv_dropdown_set_dir(play_mode, LV_DIR_BOTTOM);

    lv_dropdown_set_symbol(play_mode, LV_SYMBOL_UP);

    lv_obj_t *mode_label = lv_label_create(cont);

    lv_obj_add_style(mode_label, &font_style, 0);

    lv_label_set_text(mode_label, "mode");

    lv_obj_align_to(mode_label, play_mode, LV_ALIGN_OUT_TOP_MID, 0, 0);

//滑动条事件

static void slider_event_cb(lv_event_t * e)

    if(!start)return;

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    //puts(msg);

    if(strcmp(msg,"volume")==0)

     

        lv_obj_t * slider = lv_event_get_target(e);//获取事件对象

        char buf[8];

        int volume=(int)lv_slider_get_value(slider);//获取值

        lv_snprintf(buf, sizeof(buf), "%d",volume);

        lv_label_set_text(volume_label, buf);           //更新音量标签值

        lv_obj_align_to(volume_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

        usleep(100);            //修改音量值

        char cmd[1024]=0;

        sprintf(cmd,"volume %d 1\\n",volume);

        write(fd_mplayer,cmd,strlen(cmd));  

     

    if(strcmp(msg,"play")==0)

   

        puts("松开了");

        if(start)//启动就先暂停

        pthread_kill(tid_read,10);//暂停读mplayer返回内容      

        system("killall -19 mplayer");

        int rate = (int)lv_slider_get_value(play_slider);//获取值

        float new_time = time_length * rate * 0.01;

        int seek_time = new_time - time_pos;

        char  cmd[1024]=0;

        sprintf(cmd,"seek %d\\n",seek_time);

        //puts(cmd);

        write(fd_mplayer,cmd,strlen(cmd));

        system("killall -18 mplayer");//播放器继续

        pthread_cond_signal(&cond);//唤醒读写mplayer

        usleep(1000);

        pthread_cond_signal(&cond);//防止被再次暂停

   

//显示滑动条

static void show_slider(void)

     //音量    

    volume_slider = lv_slider_create(cont);

    lv_obj_align(volume_slider,LV_ALIGN_LEFT_MID,20,20);//位置    

    lv_obj_add_event_cb(volume_slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, "volume");//事件    

    lv_obj_set_size(volume_slider,18,180);//大小

    lv_slider_set_value(volume_slider,100,LV_ANIM_OFF);//初始值  

    /*标签 音量大小 */

    volume_label = lv_label_create(cont);

    lv_label_set_text(volume_label, "100");

    lv_obj_align_to(volume_label, volume_slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    lv_obj_t *label = lv_label_create(cont);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "volume");

    lv_obj_align_to(label, volume_label, LV_ALIGN_OUT_TOP_MID, 0, -210);

    //播放进度条

    play_slider = lv_slider_create(cont);

    lv_obj_align(play_slider,LV_ALIGN_CENTER,0,120);//位置  

    lv_obj_set_width(play_slider,400);//宽度

    lv_obj_add_event_cb(play_slider, slider_event_cb, LV_EVENT_RELEASED , "play");//事件    

    lv_slider_set_value(play_slider,0,LV_ANIM_OFF);//初始值

    lv_slider_set_range(play_slider, 0, 100);//范围

    /*在滑条下创建标签*/

    time_length_label = lv_label_create(cont);

    lv_label_set_text(time_length_label, "0:00");

    lv_obj_align_to(time_length_label, play_slider, LV_ALIGN_OUT_RIGHT_BOTTOM,0,20);

    time_pos_label = lv_label_create(cont);

    lv_label_set_text(time_pos_label, "0:00");

    lv_obj_align_to(time_pos_label, play_slider, LV_ALIGN_OUT_LEFT_BOTTOM,0,20);

//----------属于返回按钮的函数

void Back_btn(lv_event_t * e)

    system("killall -9 mplayer");

    lv_obj_del(lv_obj_get_parent((lv_obj_t *)(e->user_data)));  

//显示界面

static void display_interface()

   

    //创建背景cont,所有显示基于背景

    cont = lv_obj_create(lv_scr_act());//声明一个背景

    lv_obj_set_size(cont, 800, 480);//设置背景的范围

    lv_obj_set_style_bg_color(cont, lv_palette_main(LV_PALETTE_LIGHT_BLUE), 0);

    lv_obj_set_style_bg_grad_color(cont, lv_palette_main(LV_PALETTE_LIGHT_GREEN), 0);

    lv_obj_set_style_bg_grad_dir(cont, LV_GRAD_DIR_VER, 0);

    //基于cont背景创新返回按钮的对象

    lv_obj_t * btn_back = lv_btn_create(cont);

    lv_obj_t* lab6 = lv_label_create(btn_back);

    lv_label_set_text(lab6, "x");

    lv_obj_center(lab6);

    lv_obj_set_style_radius(btn_back,5,0);//设置对象边角为圆角 角度自己调整中间值

    lv_obj_set_size(btn_back, 30, 30);

    lv_obj_set_pos(btn_back, 0, 0);

    lv_obj_add_event_cb(btn_back, Back_btn, LV_EVENT_PRESSED, btn_back); //传入按钮父对象的父对象

   


 

    //初始化图片父对象

    init_pic_parent_obj();

    init_title_obj();

    //显示歌单列表

    show_list();

    //显示按钮

    show_button();

    //显示下拉列表

    show_drop_down();

    //显示滑动条

    show_slider();

//*********************************//

//下面是视频的函数

//获取视频的路径,检测本地节目单

void get_video_path()

    //读目录,avi后缀保存到数组

    video_num =0;

    DIR *dirp = opendir(local_video_path);

    if(dirp==NULL)

   

        perror(local_video_path);

        exit(0);

   

    struct dirent* msg;

    while(1)

   

        msg = readdir(dirp);

        if(msg == NULL)break;

        if(msg->d_name[0]=='.')continue;

        if(strstr(msg->d_name,".avi"))

       

            sprintf(video_path[video_num], "%s/%s", local_video_path, msg->d_name);

            video_num++;

            puts(video_path[video_num - 1]);

       

   

    printf("检索歌单完成 共%d\\n",video_num);

//线程任务 创建子进程播放视频

void *play_video_task(void *arg)

    printf("---- %ld线程任务------------------\\n",pthread_self());

    //拼接命令

    char cmd[1024]="mplayer -quiet -slave -zoom -x 670 -y 350 -geometry 60:0 -input file=/pipe";

    sprintf(cmd,"%s %s",cmd,video_path[video_index]);

    printf("命令:%s\\n", cmd);

   

    fp_mplayer = popen(cmd, "r");

    if (fp_mplayer == NULL)

    perror("popen fail:");

    puts("----线程任务(启动播放视频)完成 -----------------------\\n");

   

    strcpy(cmd,"get_time_length\\n");    //获取长度

    write(fd_mplayer,cmd,strlen(cmd));

    strcpy(cmd,"get_time_pos\\n");    //发送获取时间命令

    write(fd_mplayer,cmd,strlen(cmd));

   

    pthread_exit(NULL);//线程结束

//播放一个视频

void play_one_video()

 

    if(play_flag != 0)//看看有没有线程在使用播放器

   

        system("killall -9 mplayer");

   

    play_flag=1;

    printf("视频索引%d\\n", video_index);

    //打开线程播放视频

    pthread_t tid;

    int pt = pthread_create(&tid, NULL, play_video_task, NULL);

    if(pt != 0)

   

        perror("创建进程失败");

        return -1;

       

   

   

    pthread_detach(tid);//分离属性,自动回收

   

    if(!start)

   

        sleep(1);

        //读取mplayer的内容

        pthread_create(&tid_read, NULL, read_mplayer_task, NULL);//新建线程

        pthread_detach(tid_read);//分离属性,自动回收

        //发送获取时间命令

        pthread_create(&tid_write, NULL, write_mplayer_task, NULL);

        pthread_detach(tid_write);//分离属性,自动收回

        printf("tid_read %ld  tid_write %ld\\n",tid_read,tid_write);

        start=1;

   

   pthread_cond_signal(&cond);//唤醒线程读取mplayer返回的内容

   // *******************************************************************//

    //音量

    int volume=(int)lv_slider_get_value(volume_slider);

    char cmd[1024]=0;

    sprintf(cmd,"volume %d 1\\n",volume);

    write(fd_mplayer,cmd,strlen(cmd));

   

   

//视频按键事件(没写)

static void btn_handler2(lv_event_t * e)

    lv_event_code_t code = lv_event_get_code(e);

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    if(code == LV_EVENT_CLICKED) //点击按钮

   

        if(strcmp(msg,"pause") == 0)

       

            if(!start)return;

            pthread_kill(tid_read,10);//暂停读mplayer返回内容      

            system("killall -19 mplayer");

       

        if(strcmp(msg,"play") == 0)

       

            if(!start)return;

            system("killall -18 mplayer");//播放器继续

            pthread_cond_signal(&cond);//唤醒读写mplayer

            usleep(1000);

            pthread_cond_signal(&cond);//防止被再次暂停

       

        if(strcmp(msg,"forward") == 0)

       

            if(!start)return;

            usleep(1000);

            char  cmd[1024]="seek +10\\n";

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令    

       

        if(strcmp(msg,"back") == 0)

       

            if(!start)return;

            usleep(10000);

            char  cmd[1024]="seek -10\\n";

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令  

       

        if(strcmp(msg,"next_music") == 0)

       

            usleep(1000);

            if(++video_index >= video_num)video_index=0;

                play_one_video();

       

        if(strcmp(msg,"prev_music") == 0)

       

            usleep(1000);

            if(--video_index <= 0)video_index=video_num-1;

                play_one_video();

       

        if(strcmp(msg,"music_show_list") == 0)

       

            list_flag=!list_flag;

            if(list_flag)

                lv_obj_clear_flag(video_list,LV_OBJ_FLAG_HIDDEN);        

            else

                lv_obj_add_flag(video_list, LV_OBJ_FLAG_HIDDEN);

       

       

   

//显示视频按钮

static void show_button_tv()

    static lv_style_t btn_style;

    lv_style_init(&btn_style);

    lv_style_set_radius(&btn_style,90);

    lv_style_set_bg_opa(&btn_style, LV_OPA_COVER);

    lv_style_set_bg_color(&btn_style, lv_palette_lighten(LV_PALETTE_BLUE, 1));//按钮色

    //Add a shadow

    lv_style_set_shadow_width(&btn_style, 55);

    lv_style_set_shadow_color(&btn_style, lv_palette_main(LV_PALETTE_BLUE));//背景色

    //按钮的标签

    lv_obj_t *label;

    //暂停按钮

    lv_obj_t *btn_pause = lv_btn_create(cont);

    //按钮事件

    lv_obj_add_event_cb(btn_pause, btn_handler2, LV_EVENT_ALL,"pause");  

    //位置

    lv_obj_align(btn_pause, LV_ALIGN_BOTTOM_MID,40,0);

    //大小

    lv_obj_set_size(btn_pause,60,60);

    //图标

    lv_obj_set_style_bg_img_src(btn_pause,LV_SYMBOL_PAUSE,0);

   

    //播放按钮

    lv_obj_t *btn_play = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_play, btn_handler2, LV_EVENT_ALL,"play");  

    lv_obj_align(btn_play, LV_ALIGN_BOTTOM_MID,-40,0);

    lv_obj_set_size(btn_play,60,60);

    lv_obj_set_style_bg_img_src(btn_play,LV_SYMBOL_PLAY,0);

   

     //快进

    lv_obj_t *btn_forward = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_forward, btn_handler2, LV_EVENT_ALL,"forward");

    lv_obj_set_size(btn_forward,60,60);

    lv_obj_align(btn_forward, LV_ALIGN_BOTTOM_MID,120,0);

    lv_obj_set_style_bg_img_src(btn_forward,LV_SYMBOL_RIGHT LV_SYMBOL_RIGHT,0);

   

    //快退

    lv_obj_t *btn_back = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_back, btn_handler2, LV_EVENT_ALL,"back");

    lv_obj_set_size(btn_back,60,60);

    lv_obj_align(btn_back, LV_ALIGN_BOTTOM_MID,-120,0);

    lv_obj_set_style_bg_img_src(btn_back,LV_SYMBOL_LEFT LV_SYMBOL_LEFT,0);

   

    //下一首

    lv_obj_t *btn_next = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_next, btn_handler2, LV_EVENT_ALL,"next_music");

    lv_obj_set_size(btn_next,60,60);

    lv_obj_align(btn_next, LV_ALIGN_BOTTOM_MID,200,0);

    lv_obj_set_style_bg_img_src(btn_next,LV_SYMBOL_NEXT,0);

   

    //上一首

   

    lv_obj_t *btn_prev = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_prev, btn_handler2, LV_EVENT_ALL,"prev_music");

    lv_obj_set_size(btn_prev,60,60);

    lv_obj_align(btn_prev, LV_ALIGN_BOTTOM_MID,-200,0);

    lv_obj_set_style_bg_img_src(btn_prev,LV_SYMBOL_PREV,0);

   

    //显示,隐藏  歌单列表

    //风格设置

    static lv_style_t style;

    lv_style_init(&style);

    //设置背景颜色和半径

    lv_style_set_radius(&style, 5);

    lv_style_set_bg_opa(&style, LV_OPA_COVER);

    lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));

    //添加一个影子

    lv_style_set_shadow_width(&style, 55);

    lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE));

    //视频单列表

    lv_obj_t *btn_list = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_list, btn_handler2, LV_EVENT_ALL,"music_show_list");

    lv_obj_set_size(btn_list,60,60);

    lv_obj_align(btn_list, LV_ALIGN_BOTTOM_RIGHT,-20,0);

    label = lv_label_create(btn_list);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "menu");

    lv_obj_center(label);

   

//视频滑动条事件

static void slider_event_cb2(lv_event_t * e)

    if(!start)return;

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    //puts(msg);

    if(strcmp(msg,"volume")==0)

     

        lv_obj_t * slider = lv_event_get_target(e);//获取事件对象

        char buf[8];

        int volume=(int)lv_slider_get_value(slider);//获取值

        lv_snprintf(buf, sizeof(buf), "%d",volume);

        lv_label_set_text(volume_label, buf);           //更新音量标签值

        lv_obj_align_to(volume_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

        usleep(100);            //修改音量值

        char cmd[1024]=0;

        sprintf(cmd,"volume %d 1\\n",volume);

        write(fd_mplayer,cmd,strlen(cmd));  

     

    if(strcmp(msg,"play")==0)

   

        puts("松开了");

        if(start)//启动就先暂停

       

            pthread_kill(tid_read,10);//暂停读mplayer返回内容      

            system("killall -19 mplayer");

       

        int rate = (int)lv_slider_get_value(play_slider);//获取值

        float new_time = time_length * rate * 0.01;

        int seek_time = new_time - time_pos;

        char  cmd[1024]=0;

        sprintf(cmd,"seek %d\\n",seek_time);

        //puts(cmd);

        write(fd_mplayer,cmd,strlen(cmd));

        system("killall -18 mplayer");//播放器继续

        pthread_cond_signal(&cond);//唤醒读写mplayer

        usleep(1000);

        pthread_cond_signal(&cond);//防止被再次暂停

   

//视频显示滑动条

static void show_slider_tv(void)

     //音量    

    volume_slider = lv_slider_create(cont);

    lv_obj_align(volume_slider,LV_ALIGN_LEFT_MID,0,20);//位置    

    lv_obj_add_event_cb(volume_slider, slider_event_cb2, LV_EVENT_VALUE_CHANGED, "volume");//事件    

    lv_obj_set_size(volume_slider,18,180);//大小

    lv_slider_set_value(volume_slider,100,LV_ANIM_OFF);//初始值  

    //标签 音量大小

    volume_label = lv_label_create(cont);

    lv_label_set_text(volume_label, "100");

    lv_obj_align_to(volume_label, volume_slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);

    lv_obj_t *label = lv_label_create(cont);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "volume");

    lv_obj_align_to(label, volume_label, LV_ALIGN_OUT_TOP_MID, 0, -210);

    //播放进度条

    play_slider = lv_slider_create(cont);

    lv_obj_align(play_slider,LV_ALIGN_CENTER,0,135);//位置  

    lv_obj_set_width(play_slider,600);//宽度

    lv_obj_add_event_cb(play_slider, slider_event_cb2, LV_EVENT_RELEASED , "play");//事件    

    lv_slider_set_value(play_slider,0,LV_ANIM_OFF);//初始值

    lv_slider_set_range(play_slider, 0, 100);//范围

    //在滑条下创建标签

    time_length_label = lv_label_create(cont);

    lv_label_set_text(time_length_label, "0:00");

    lv_obj_align_to(time_length_label, play_slider, LV_ALIGN_OUT_RIGHT_BOTTOM,0,20);

    time_pos_label = lv_label_create(cont);

    lv_label_set_text(time_pos_label, "0:00");

    lv_obj_align_to(time_pos_label, play_slider, LV_ALIGN_OUT_LEFT_BOTTOM,0,20);

//列表处理函数,播放列表中的视频(没写)

static lv_event_cb_t event_handler_video_list(lv_event_t * e)

   //获取事件码

    lv_event_code_t code = lv_event_get_code(e);

    //获取事件对象,这里是按钮

    lv_obj_t * obj = lv_event_get_target(e);

    //如果点击按钮

    if(code == LV_EVENT_CLICKED)

   

        printf("Clicked  %s\\n", lv_list_get_btn_text(video_list, obj));

        //当前播放中的video下标更新为点击列表的下标

        video_index = lv_event_get_user_data(e);

        play_one_video();

   

//显示节目单列表

static void show_list2()

    //创建列表文本框

    video_list = lv_list_create(cont);

    //添加风格

    lv_obj_add_style(video_list, &font_style, 0);

    lv_obj_set_size(video_list, 75, 300);

    //列表位置

    //lv_obj_center(music_list);

    lv_obj_align(video_list, LV_ALIGN_RIGHT_MID, 5, -80);

    //添加文本

    lv_list_add_text(video_list, "list");

    //在列表中添加按钮

    lv_obj_t *btn;

    for(int i = 0; i < video_num; i++)

   

        char tmp[100]=0;

        char *p = video_path[i];

        p = strrchr(p,'/');

        strcpy(tmp,++p);//裁剪

        // 参数:列表对象,图标宏,按钮名

        btn = lv_list_add_btn(video_list, NULL,strtok(tmp,"."));

        //列表按钮风格

        lv_obj_add_style(video_list, &font_style, 0);

        // 触发事件,把下标传递

        lv_obj_add_event_cb(btn, event_handler_video_list, LV_EVENT_CLICKED, i);

   


 

static void k(lv_event_t *e)

    system("killall -9 mplayer");

//视频显示界面

static void display_interface2()

    //创建背景cont,所有显示基于背景

    cont = lv_obj_create(lv_scr_act());//声明一个背景

    lv_obj_set_size(cont, 800, 480);//设置背景的范围

    lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);

    //基于cont背景创新返回按钮的对象

    lv_obj_t *btn_back = lv_btn_create(cont);

    lv_obj_t *lab6 = lv_label_create(btn_back);

    lv_label_set_text(lab6, "x");

    lv_obj_center(lab6);

    lv_obj_set_style_radius(btn_back,5,0);//设置对象边角为圆角 角度自己调整中间值

    lv_obj_set_size(btn_back, 30, 30);

    lv_obj_set_pos(btn_back, 0, 0);

    lv_obj_add_event_cb(btn_back, Back_btn, LV_EVENT_PRESSED, btn_back); //传入按钮父对象的父对象

    //整一个杀视频的按钮

   

    lv_obj_t* btn01 = lv_btn_create(cont);

    lv_obj_align(btn01, LV_ALIGN_BOTTOM

粤嵌gec6818LED屏幕上画图 太极图 图片显示 电子相册 2048小游戏 实现识别触摸坐标的识别 电子自助点餐设计等项目

交叉开发
    在一个有编辑/编译功能的PC机上进行编辑/编译,生成的可执行文件通过
    交叉开发工具下载到目标机(GEC-6818)
    
    开发板 --- Linux内核 --- Linux指令
    首先创建自己的工作目录
    
    mkdir xxx
    
    下载交叉编译生成的可执行文件:
        rx 可执行文件名
        传输 --- 发送xmodem --- 浏览到我们所要发送的文件 --- 选中 --- 发送
        如果发送的是一个可执行文件,没有可执行的权限
            chmod +x 可执行文件名  --- 再去运行
        !!! 下载可执行文件必须是交叉编译生成的
        arm-linux-gcc 源文件名 -o 可执行文件名    

2 屏幕操作
    屏幕分辨率:800*480
    800 一行有800个像素点 480行
    像素点:显示颜色的最小单位
    颜色:ARGB --- 每个分量一个字节 
        A:透明度
        R:红色分量 0 - ff
        G:绿色分量
        B:蓝色分量
                
        绿色:0x0000ff00        
                
    如果我们想要绿屏:
        每个像素点全部显示绿色:0x0000ff00
        
    打开屏幕
        int lcd_fd = open("/dev/fb0",O_RDWR);
        if(lcd_fd == -1)
        
            perror("open lcd fail");
            return -1;
        
    操作屏幕
        //写入数据
        int color[800*480]=0;
        for(int i=0;i<480;i++)
        
            for(int j=0;j<800;j++)
            
                color[i*800+j]=0x0000ff00;
            
        
        write(lcd_fd,color,800*480*4);
    关闭屏幕
        close(lcd_fd);

因为引用了 #include<math.h> 

切记 切记 Liunx 编译时 要加 -lm

类似 arm-linux-gcc 1.c -lm

画太极图

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/mman.h>
#include<unistd.h>
#include<math.h> 
int *plcd = NULL;
#define WHITE 0x00FFFFFF 
#define BLAK 0x00000000 
void draw_point(int x, int y, int color)

	if (x >= 0 && x<800 && y >= 0 && y<480)
	
		*(plcd + y * 800 + x) = color;
	
	


void draw_circle(int x, int y,double r ,int color)

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				double all=(i-x)*(i-x)+(j-y)*(j-y);
				double fc=sqrt(all);
				if(r>fc)
				
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
				
			
	
	
	


void draw_circle_b(int x, int y,double r ,int color)

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				if(i<x)
					double all=(i-x)*(i-x)+(j-y)*(j-y);
					double fc=sqrt(all);
					if(r>fc)
					
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
										
				
			
	
	
	


void clear(int color)

	int x,y;
	for(y=0;y<480;y++)
	
		for(x=0;x<800;x++)
		
			draw_point(x,y,color);
		
	


int main()

	int lcd_fd = open("/dev/fb0",O_RDWR);
	if (lcd_fd == -1)
	
		perror("open lcd fail");
	
	plcd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd,0);
	if (plcd==NULL)
	
		perror("mmao  fail");
	
	int color = 0x0000FFFF;
	
    clear(0x00666666);
	draw_circle(240, 400,200, BLAK);
	draw_circle_b(240, 400,200, WHITE);
    draw_circle(240, 300,100, WHITE); 
    draw_circle(240, 500,100, BLAK); 
    draw_circle(240, 300,25, BLAK); 
    draw_circle(240, 500,25, WHITE); 

//	draw_circle(240, 400,50, color);  
	close(lcd_fd);
	munmap(plcd,800*480*4);
	return 0;






画笑脸

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/mman.h>
#include<unistd.h>
#include<math.h> 

#define WHITE 0x00FFFFFF 
#define BLAK 0x00000000 
#define org 0x00CDAD00
#define gray 0x00CD853F 

int *plcd = NULL;  

void draw_point(int x, int y, int color)

	if (x >= 0 && x<800 && y >= 0 && y<480)
	
		*(plcd + y * 800 + x) = color;
	
	


void draw_circle(int x, int y,double r ,int color)//HUAYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				double all=(i-x)*(i-x)+(j-y)*(j-y);
				double fc=sqrt(all);
				if(r>fc)
				
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
				
			
	
	
	


void draw_circle_b(int x, int y,double r ,int color)//BANYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				if(i<x)
					double all=(i-x)*(i-x)+(j-y)*(j-y);
					double fc=sqrt(all);
					if(r>fc)
					
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
										
				
			
	
	
	


void draw_circle_c(int x, int y,double r ,int color)//BANYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				if(i>x)
					double all=(i-x)*(i-x)+(j-y)*(j-y);
					double fc=sqrt(all);
					if(r>fc)
					
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
										
				
			
	
	
	


void clear(int color)

	int x,y;
	for(y=0;y<480;y++)
	
		for(x=0;x<800;x++)
		
			draw_point(x,y,color);
		
	



int main()

	int lcd_fd = open("/dev/fb0",O_RDWR);
	if (lcd_fd == -1)
	
		perror("open lcd fail");
	
	plcd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd,0);
	if (plcd==NULL)
	
		perror("mmap  fail");
	
	int color = 0x0000FFFF;
	
    clear(0x00666666);
	draw_circle(240, 400,200, org);//画橙底 
	
	//draw_circle(180, 480,30, HUI);//眼睛1 
    //draw_circle(180, 320,30, HUI); //眼睛2 
    
    draw_circle_b(170, 300,50, gray); 
     draw_circle_b(170, 300,40, org);
     
     draw_circle_b(170, 500,50, gray); 
     draw_circle_b(170, 500,40, org);
	  
    //draw_circle(240, 300,25, BLAK); 
    //draw_circle(240, 500,25, WHITE); 
    draw_circle_c(250, 400,150, WHITE);
  
//	draw_circle(240, 400,50, color);  
  int x,y;
	for(y=0;y<480;y++)
	
		for(x=0;x<800;x++)
		
			if (x >=400 && x<402 && y >=250 && y<400 )
			draw_point(x,y,BLAK);
			if (x >=300 && x<302 && y >=250 && y<362 )
			draw_point(x,y,BLAK);
			if (x >=500 && x<502 && y >=250 && y<362 )
			draw_point(x,y,BLAK);
		
	
	close(lcd_fd);
	munmap(plcd,800*480*4);
	return 0;





画微笑

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/mman.h>
#include<unistd.h>
#include<math.h> 

#define WHITE 0x00FFFFFF 
#define BLAK 0x00000000 
#define org 0x00CDAD00
#define HUI 0x00CD853F 

int *plcd = NULL;  

void draw_point(int x, int y, int color)

	if (x >= 0 && x<800 && y >= 0 && y<480)
	
		*(plcd + y * 800 + x) = color;
	
	


void draw_circle(int x, int y,double r ,int color)//HUAYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				double all=(i-x)*(i-x)+(j-y)*(j-y);
				double fc=sqrt(all);
				if(r>fc)
				
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
				
			
	
	
	


void draw_circle_b(int x, int y,double r ,int color)//BANYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				if(i>x)
					double all=(i-x)*(i-x)+(j-y)*(j-y);
					double fc=sqrt(all);
					if(r>fc)
					
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
										
				
			
	
	
	


void clear(int color)

	int x,y;
	for(y=0;y<480;y++)
	
		for(x=0;x<800;x++)
		
			draw_point(x,y,color);
		
	


int main()

	int lcd_fd = open("/dev/fb0",O_RDWR);
	if (lcd_fd == -1)
	
		perror("open lcd fail");
	
	plcd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd,0);
	if (plcd==NULL)
	
		perror("mmao  fail");
	
	int color = 0x0000FFFF;
	
    clear(0x00666666);
	draw_circle(240, 400,200, org);//画橙底 
	
	draw_circle(180, 480,30, HUI);//眼睛1 
    draw_circle(180, 320,30, HUI); //眼睛2 
    
    draw_circle_b(270, 400,50, HUI); 
     draw_circle_b(270, 400,40, org); 
    //draw_circle(240, 300,25, BLAK); 
    //draw_circle(240, 500,25, WHITE); 

//	draw_circle(240, 400,50, color);  
	close(lcd_fd);
	munmap(plcd,800*480*4);
	return 0;






 四叶草 彩虹

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/mman.h>
#include<unistd.h>
#include<math.h> 

#define WHITE 0x00FFFFFF 
#define BLAK 0x00000000 
#define org 0x00CDAD00
#define HUI 0x00CD853F 

int *plcd = NULL;  

void draw_point(int x, int y, int color)

	if (x >= 0 && x<800 && y >= 0 && y<480)
	
		*(plcd + y * 800 + x) = color;
	
	


void draw_circle(int x, int y,double r ,int color)//HUAYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				double all=(i-x)*(i-x)+(j-y)*(j-y);
				double fc=sqrt(all);
				if(r>fc)
				
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
				
			
	
	
	


void draw_circle_b(int x, int y,double r ,int color)//BANYUAN

	if (x >= 0 && x<480 && y >= 0 && y<800)
	
		for (double i = 0; i < 480; i++)
    
		for (double j = 0; j < 800; j++)
			
				if(i>x)
					double all=(i-x)*(i-x)+(j-y)*(j-y);
					double fc=sqrt(all);
					if(r>fc)
					
						draw_point(j, i, color);
					//	printf("fc=%lf\\n",fc);
										
				
			
	
	
	


void clear(int color)

	int x,y;
	for(y=0;y<480;y++)
	
		for(x=0;x<800;x++)
		
			draw_point(x,y,color);
		
	


int main()

	int lcd_fd = open("/dev/fb0",O_RDWR);
	if (lcd_fd == -1)
	
		perror("open lcd fail");
	
	plcd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED,lcd_fd,0);
	if (plcd==NULL)
	
		perror("mmao  fail");
	
	int color = 0x0000FFFF;
	
    clear(0x00666666);
   while(1)
   
 
     int x,y; 
   
   for(x=0;x<800;x++)
		for(y=0;y<480;y++)
			if(y<160)
				*(plcd + y * 800 + x) = 0x0000ff00;
			else if(y<320)
				*(plcd + y * 800 + x) = 0x000000ff;
			else
				*(plcd + y * 800 + x) = 0x00ff0000;


	draw_circle(240, 400,200, org);//画橙底 
	
    draw_circle_b(270, 400,50, HUI); 
     draw_circle_b(270, 400,40, org); 
    

    draw_circle(180, 480,30, HUI);//眼睛1 
    draw_circle(180, 320,30, HUI); //眼睛2 
    
	
	int i,j;
    int cir_color[480][800];
	for(i=0;i<480;i++)
	
		for(j=0;j<800;j++)
		
			if((i-480)*(i-480) + (j-400)*(j-400)<51*51)
				cir_color[i][j]=0x00FF0033;
			else if((i-480)*(i-480) + (j-400)*(j-400)<107*107)
				cir_color[i][j]=0x00FF6600;
			else if((i-480)*(i-480) + (j-400)*(j-400)<168*168)
				cir_color[i][j]=0x00FFFF00;
			else if((i-480)*(i-480) + (j-400)*(j-400)<234*234)
				cir_color[i][j]=0x0000FF00;
			else if((i-480)*(i-480) + (j-400)*(j-400)<307*307)
				cir_color[i][j]=0x0000FFFF;
			else if((i-480)*(i-480) + (j-400)*(j-400)<385*385)
				cir_color[i][j]=0x000000FF;
			else
				cir_color[i][j]=0x00FF00CC;
					
	

    lcd_fd = open("/dev/fb0",O_RDWR);
	if(-1 == lcd_fd)
	
		printf("open lcd error\\n");
	
	write(lcd_fd,cir_color,800*480*4);

sleep(2);
   
    int si_color[480][800];
	for(i=0;i<480;i++)
	
		//遍历二维数组每一行的每一列
		for(j=0;j<800;j++)
		
			int a =  (i-150)*(i-150) + (j-300)*(j-300);
			int b = (i-330)*(i-330) + (j-300)*(j-300);
			int c = (i-150)*(i-150) + (j-500)*(j-500);
			int d = (i-330)*(i-330) + (j-500)*(j-500);
			int r2 = 150*150;
 
			if (a<r2 && b<r2)
				si_color[i][j]=0x00FF0033;
			else if(a<r2 && c<r2)
				si_color[i][j]=0x00FF6600;
			else if(b<r2 && d<r2)
				si_color[i][j]=0x00FFFF00;
			else if(c<r2 && d<r2)
				si_color[i][j]=0x0000FF00;
			else
				si_color[i][j]=0x00FF00CC;
					
	
lcd_fd = open("/dev/fb0",O_RDWR);
	if(-1 == lcd_fd)
	
		printf("open lcd error\\n");
	
	write(lcd_fd,si_color,800*480*4);

   
   sleep(1);


   
	close(lcd_fd);
	munmap(plcd,800*480*4);
	return 0;





切记 切记 Liunx 编译时 要加 -lm

电子相册代码实现

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <math.h>
#include <stdlib.h>
int * p = NULL ;

void draw_point(int x,int y,int color)

	if(x>=0 && x<800 && y>=0 && y<480 )
	
		*(p+800*y+x) = color ;
	


void show_bmp (char * pathname ,int x ,int y)

	int fd = open(pathname,O_RDONLY);
	if(fd == -1)
	
		perror("open error\\n");
		return ;
	
	int fd1 = open("/dev/fb0",O_RDWR);
	if(fd1 == -1)
	
		perror("open error\\n");
		return ;
	
	printf("open success\\n");
	
	p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED ,fd1,0);
	if(p == NULL )
	
		perror("mmap error\\n");
		return ;
	
	int width,height;
	short depth;
	unsigned char buf[4] ;
	//读取宽度
	lseek(fd,0x12,SEEK_SET);
	read(fd,buf,4);
	width = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];
	//读取高度
	read(fd,buf,4);
	height  = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];
	//读取色深
	lseek(fd,0x1c,SEEK_SET);
	read(fd,buf,2);
	depth = buf[1] << 8  | buf[0];
	//打印信息
	printf("width = %d  height = %d  depth = %d \\n",width,height,depth);

	
	int line_valid_bytes = abs(width) * depth / 8 ; 
	int laizi=0;
	if( (line_valid_bytes % 4) !=0   )
	
		laizi =  4 - line_valid_bytes%4;
	
	int line_bytes = line_valid_bytes  +  laizi ;
	
	int total_bytes = line_bytes * abs(height) ; 
	
	unsigned char * p1  = malloc(total_bytes);
	
	lseek(fd,54,SEEK_SET);
	read(fd,p1,total_bytes);
	
	
	unsigned char a ,r ,g, b ;
	int i = 0;
	int x0=0,y0=0; 
	int color ;
	for(y0=0;y0<abs(height);y0++)
	
		for(x0=0;x0<abs(width);x0++)
		
			
		
			b = p1[i++];
			g = p1[i++];
			r = p1[i++];
			if(depth == 32)
			
				a=p1[i++];
			
			if(depth == 24)
			
				a = 0;
			
			color = a << 24 | r << 16 | g << 8 | b ;
			draw_point(width>0?x+x0:abs(width)+x-1-x0,
					height>0? y+height-1-y0 : y+y0,color);
			
			
		
		i = i +laizi ;
			
	
	free(p1);
	close(fd1);
	munmap(p,800*480*4);
	close(fd);
	

int main()

	while(1)
	
	
	show_bmp("1.bmp",0 ,0);// 自己存储的图片
	sleep(2);
	show_bmp("2.bmp",0 ,0);
	sleep(2);
	show_bmp("3.bmp",0 ,0);
	sleep(2);
	show_bmp("4.bmp",0 ,0);
	sleep(2);
	show_bmp("5.bmp",0 ,0);
	sleep(2);

	return 0;

横行打开

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <math.h>
#include <stdlib.h>
#define RGB_SIZE 800*480*3
#define LCD_SIZE 800*480
int *plcd=NULL;
int photo(char *a)

	
	
	// 1. 打开触摸屏文件
	int lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	
		printf("Open lcd failed!!\\n");
		return -1;
	
	
	// 2. 打开bmp图片
	int bmp_fd = open(a, O_RDWR);
	
	
	// 3. 偏移bmp格式头, 54个字节
	off_t offset = lseek(bmp_fd, 54, SEEK_SET);
	if (offset == -1)
	
		printf("Offset failed!\\n");
		return -1;
	
	
	// 4. 读取bmp图片的RGB值,将读到的值存进bmp_rgb数组中
	char bmp_buf[RGB_SIZE] = ;
	size_t re_ret = read(bmp_fd, bmp_buf, RGB_SIZE);
	
	
	// 5. 24位数据-->32位数据:bmp图片rgb占3个字节,lcdargb占4个字节. char占1个字节大小,int占4个字节大小
	int lcd_buf[LCD_SIZE] = ;
	int i;
	for (i=0; i<LCD_SIZE; i++)
	
		lcd_buf[i] = bmp_buf[i*3+2]<<16 | bmp_buf[i*3+1]<<8 | bmp_buf[i*3+0]<<0;
	
	
	// 6. 翻转180°
	int fli_buf[LCD_SIZE];
	int x, y;
	for(y = 0; y < 480; y++)
	
		for(x = 0; x < 800; x++)
		
			fli_buf[y*800+x] = lcd_buf[(479-y)*800+x];
		
		
	
	
	// 7. 写入LCD
	
	plcd=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
		if(plcd == NULL)
		
			perror("mmap fail");
		
		for(int x=0;x<800;x++)
		
			for(int y=0;y<480;y++)
			
				*(plcd+x+y*800)=fli_buf[x+y*800];
							
			sleep(0.1);
			
	// 8. 关闭文件
	close(lcd_fd);
	close(bmp_fd);	
	return 0;

int photo2(char *a)

	
	
	// 1. 打开触摸屏文件
	int lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	
		printf("Open lcd failed!!\\n");
		return -1;
	
	
	// 2. 打开bmp图片
	int bmp_fd = open(a, O_RDWR);
	
	
	// 3. 偏移bmp格式头, 54个字节
	off_t offset = lseek(bmp_fd, 54, SEEK_SET);
	if (offset == -1)
	
		printf("Offset failed!\\n");
		return -1;
	
	
	// 4. 读取bmp图片的RGB值,将读到的值存进bmp_rgb数组中
	char bmp_buf[RGB_SIZE] = ;
	size_t re_ret = read(bmp_fd, bmp_buf, RGB_SIZE);
	
	
	// 5. 24位数据-->32位数据:bmp图片rgb占3个字节,lcdargb占4个字节. char占1个字节大小,int占4个字节大小
	int lcd_buf[LCD_SIZE] = ;
	int i;
	for (i=0; i<LCD_SIZE; i++)
	
		lcd_buf[i] = bmp_buf[i*3+2]<<16 | bmp_buf[i*3+1]<<8 | bmp_buf[i*3+0]<<0;
	
	
	// 6. 翻转180°
	int fli_buf[LCD_SIZE];
	int x, y;
	for(y = 0; y < 480; y++)
	
		for(x = 0; x < 800; x++)
		
			fli_buf[y*800+x] = lcd_buf[(479-y)*800+x];
		
		
	
	
	// 7. 写入LCD
	
			plcd=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
		if(plcd == NULL)
		
			perror("mmap fail");
		
		
			for(int y=0;y<480;y++)
		
			for(int x=0;x<800;x++)
			
				*(plcd+x+y*800)=fli_buf[x+y*800];
				
				
			sleep(0.1);
		
	
	// 8. 关闭文件
	close(lcd_fd);
	close(bmp_fd);
	
	
	return 0;

int photo3(char *a)

	
	
	// 1. 打开触摸屏文件
	int lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	
		printf("Open lcd failed!!\\n");
		return -1;
	
	
	// 2. 打开bmp图片
	int bmp_fd = open(a, O_RDWR);
	
	
	// 3. 偏移bmp格式头, 54个字节
	off_t offset = lseek(bmp_fd, 54, SEEK_SET);
	if (offset == -1)
	
		printf("Offset failed!\\n");
		return -1;
	
	
	// 4. 读取bmp图片的RGB值,将读到的值存进bmp_rgb数组中
	char bmp_buf[RGB_SIZE] = ;
	size_t re_ret = read(bmp_fd, bmp_buf, RGB_SIZE);
	
	
	// 5. 24位数据-->32位数据:bmp图片rgb占3个字节,lcdargb占4个字节. char占1个字节大小,int占4个字节大小
	int lcd_buf[LCD_SIZE] = ;
	int i;
	for (i=0; i<LCD_SIZE; i++)
	
		lcd_buf[i] = bmp_buf[i*3+2]<<16 | bmp_buf[i*3+1]<<8 | bmp_buf[i*3+0]<<0;
	
	
	// 6. 翻转180°
	int fli_buf[LCD_SIZE];
	int x, y;
	for(y = 0; y < 480; y++)
	
		for(x = 0; x < 800; x++)
		
			fli_buf[y*800+x] = lcd_buf[(479-y)*800+x];
		
		
	
	
	// 7. 写入LCD
	
	plcd=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
		if(plcd == NULL)
		
			perror("mmap fail");
		
		
		for(int x=0;x<400;x++)
		
			for(int y=0;y<240;y++)
			
				*(plcd+x+y*800)=fli_buf[x+y*800];
							
			sleep(0.1);
		
		for(int x=400;x<800;x++)
		
			for(int y=0;y<240;y++)
			
				*(plcd+x+y*800)=fli_buf[x+y*800];
							
			sleep(0.1);
		
		
		for(int x=0;x<400;x++)
		
			for(int y=240;y<480;y++)
			
				*(plcd+x+y*800)=fli_buf[x+y*800];
			
			sleep(0.1);
		
		for(int x=400;x<800;x++)
		
			for(int y=240;y<480;y++)
			
				*(plcd+x+y*800)=fli_buf[x+y*800];
			
			sleep(0.1);
		

	
	
	// 8. 关闭文件
	close(lcd_fd);
	close(bmp_fd);
	
	
	return 0;

void main()
	while(1)
        
	
	photo3("./1.bmp");
                sleep(0.5);
	photo3("./2.bmp");
	        sleep(0.5);
	photo("./3.bmp");
                sleep(0.5);
                
	
     

如何使用触摸屏
    Linux为输入事件提供了一个专门的结构体
    #include <linux/input.h>
    struct input_event
    
        struct timeval time;//记录事件发生的时间
        _u16 type;    //记录事件的类型
            type == EV_ABS  触摸屏事件
            type == EV_KEY    按键事件
        _u16 code;    //随着type的改变而改变
            type == EV_ABS
                code == ABS_X x轴
                code == ABS_y y轴
            type == EV_KEY
                code == BTN_TOUCH
        _s32 value;    //随着code的变化而变化
            code == ABS_X
                value = x x值
            code == ABS_Y
                value = y y值
            code == BTN_TOUCH
                value == 0    表示松开
                value == 1  表示按下
        
    

    触摸屏的获取
        获取坐标
        打开设备 --- 读取内容 --- 解析 --- 关闭设备
        int touch_fd = open("/dev/input/event0",O_RDONLY);
        if(touch_fd == -1)
        
            perror("open touch fail");
            return -1;
        
        struct input_event ev;
        int x=-1,y=-1;
        while(1)
        
            read(touch_fd,&ev,sizeof(ev));
            if(ev.type == EV_ABS && ev.code == ABS_X)
            
                x = ev.value;
            
            if(ev.type == EV_ABS && ev.code == ABS_Y)
            
                y = ev.value;
            
            if(ev.type == EV_KEY && ev.code == BTN_TOUCH)
            
                if(ev.value == 0)
                
                    printf("Release\\n");
                    break;
                
                else if(ev.value == 1)
                
                    printf("Press\\n");
                
            
        
        printf("x=%d y=%d\\n",x,y);
        
        close(touch_fd);

#include <stdio.h>//printf
#include <linux/input.h>//struct input_event
#include <sys/types.h>//open
#include <sys/stat.h>//open
#include <fcntl.h>//open
#include <unistd.h>//read
#include <stdlib.h>
#include <sys/mman.h>
#include<linux/fb.h>
#include <math.h>
int * p = NULL ;

void draw_point(int x,int y,int color)

	if(x>=0 && x<800 && y>=0 && y<480 )
	
		*(p+800*y+x) = color ;
	


void show_bmp (char * pathname ,int x ,int y)

	int fd = open(pathname,O_RDONLY);
	if(fd == -1)
	
		perror("open error\\n");
		return ;
	
	int fd1 = open("/dev/fb0",O_RDWR);
	if(fd1 == -1)
	
		perror("open error\\n");
		return ;
	
	printf("open success\\n");
	
	p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED ,fd1,0);
	if(p == NULL )
	
		perror("mmap error\\n");
		return ;
	
	int width,height;
	short depth;
	unsigned char buf[4] ;
	//读取宽度
	lseek(fd,0x12,SEEK_SET);
	read(fd,buf,4);
	width = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];
	//读取高度
	read(fd,buf,4);
	height  = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];
	//读取色深
	lseek(fd,0x1c,SEEK_SET);
	read(fd,buf,2);
	depth = buf[1] << 8  | buf[0];
	//打印信息
	printf("width = %d  height = %d  depth = %d \\n",width,height,depth);

	
	int line_valid_bytes = abs(width) * depth / 8 ; 
	int laizi=0;
	if( (line_valid_bytes % 4) !=0   )
	
		laizi =  4 - line_valid_bytes%4;
	
	int line_bytes = line_valid_bytes  +  laizi ;
	
	int total_bytes = line_bytes * abs(height) ; 
	
	unsigned char * p1  = malloc(total_bytes);
	
	lseek(fd,54,SEEK_SET);
	read(fd,p1,total_bytes);
	
	
	unsigned char a ,r ,g, b ;
	int i = 0;
	int x0=0,y0=0; 
	int color ;
	for(y0=0;y0<abs(height);y0++)
	
		for(x0=0;x0<abs(width);x0++)
		
			
		
			b = p1[i++];
			g = p1[i++];
			r = p1[i++];
			if(depth == 32)
			
				a=p1[i++];
			
			if(depth == 24)
			
				a = 0;
			
			color = a << 24 | r << 16 | g << 8 | b ;
			draw_point(width>0?x+x0:abs(width)+x-1-x0,
					height>0? y+height-1-y0 : y+y0,color);		
		
		i = i +laizi ;
			
	
	
	free(p1);
	close(fd1);
	munmap(p,800*480*4);
	close(fd);
	
int main()
	
int touch_fd = open("/dev/input/event0",O_RDONLY);
		if(touch_fd == -1)
		
			perror("open touch fail");
			return -1;
		
		struct input_event ev;
		int x=-1,y=-1;
	while(1)

				while(1)
	
			
	
			read(touch_fd,&ev,sizeof(ev));
			if(ev.type == EV_ABS && ev.code == ABS_X)
			
				x = ev.value;
			
			if(ev.type == EV_ABS && ev.code == ABS_Y)
			
				y = ev.value;
			
			if(ev.type == EV_KEY && ev.code == BTN_TOUCH)
			
				if(ev.value == 0)
				
					printf("Release\\n");
					break;
				
				else if(ev.value == 1)
				
					printf("Press\\n");
				
			
		
		printf("x=%d y=%d\\n",x,y);
		
		if (x>0&& y<400)
		
			show_bmp("1.bmp", 0, 0);
		
		if (x>400 && y<800)
		
			show_bmp("2.bmp", 0, 0);
		


		close(touch_fd);
		
 		return 0;		

2048小游戏c语言代码

2048游戏规则:每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。

参考思路 :

第一步
    给屏幕上背景色(红、蓝....)
    
第二步
    中心画一个正方形400*400(这里也可以画大一点,每张图之间保留一点空隙,使游戏更美观)

第三步
    找11张100*100的图片(2,4,8,16...2048)
    
第四步
    初始化棋盘,游戏开始,在16个位置上随机出现2,4,8中的一张图片,共出现3张
    (概率自己弄,如出现2的概率50%,4个概率25%,8个概率25%)
    
第五步
    手指滑屏怎么实现图片的上下左右移动,同时相同的图片相加变成一张图片
    如,两张图片2变更成一张图片4
    
    同时,滑动后在没有图片的地方生成一张新的图片(同第四步,只是这里出现一张图)
    
第六步
    判断游戏结束
    
 

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include<linux/fb.h>
#include <math.h>
#include <errno.h>
#include <time.h>


int lcd_fd, ts_fd;
int *lcd_ptr;
int game_over;
int get_finger_direction();



struct bmp_header 		//14
	unsigned char type[2];
	unsigned long size;
	unsigned short reserverd1;
	unsigned short reserverd2;
	unsigned long offbit;
__attribute__((packed));		//字节对齐

struct bmp_info 	//40
	unsigned int size;
	unsigned int width;
	unsigned int height;
	unsigned short planes;
	unsigned short bitcount;
	unsigned int bitcompression;
	unsigned int sizeimg;
	unsigned int xpelspermeter;
	unsigned int ypelspermeter;
	unsigned int biclrused;
	unsigned int important;
__attribute__((packed));		//字节对齐


//数组初始化,将所有的图片保存在一个数组中
const char *bmp_files[] = 
	"/pic/bmp/digit_2.bmp", "/pic/bmp/digit_4.bmp",
	"/pic/bmp/digit_8.bmp", "/pic/bmp/digit_16.bmp",
	"/pic/bmp/digit_32.bmp", "/pic/bmp/digit_64.bmp",
	"/pic/bmp/digit_128.bmp", "/pic/bmp/digit_256.bmp",
	"/pic/bmp/digit_512.bmp", "/pic/bmp/digit_1024.bmp",
	"/pic/bmp/digit_2048.bmp", "/pic/bmp/digit_4096.bmp",
	"/pic/bmp/digit_8192.bmp", "/pic/bmp/digit_16384.bmp",
	"/pic/bmp/digit_32768.bmp", "/pic/bmp/digit_65536.bmp"
;

//棋盘矩阵的初始化
int array[4][4] = 0;

//根据要显示的数字来返回对应的文件名的下标
int get_bmp_files_index(int x)

	if (x == 2) 
		return 0;
	else if (x == 4) 
		return 1;
	else if (x == 8) 
		return 2;
	else if (x == 16) 
		return 3;
	else if (x == 32) 
		return 4;
	else if (x == 64) 
		return 5;
	else if (x == 128) 
		return 6;
	else if (x == 256) 
		return 7;
	else if (x == 512) 
		return 8;
	else if (x == 1024) 
		return 9;
	else if (x == 2048) 
		return 10;
	else if (x == 4096) 
		return 11;
	else if (x == 8192) 
		return 12;
	else if (x == 16384) 
		return 13;
	else if (x == 32768) 
		return 14;
	else if (x == 65536) 
		return 15;
	
	
	return -1;


//求棋盘矩阵里面有多少个0
int rectangle_get_zero_num()

	int i, j, count = 0;
	for (i = 0; i < 4; i++) 
		for (j = 0; j < 4; j++) 
			if (array[i][j] == 0) 
				count++;
			
		
	
	
	return count;


int rectangle_set_value(int z, int value)

	int i, j, count = 0;
	for (i = 0; i < 4; i++) 
		for (j = 0; j < 4; j++) 
				if (array[i][j] == 0) 
					count++;
					if (count == z) 
						array[i][j] = value;
						return 0;
					
				
				
		
	


//触摸屏滑屏算法实现
int get_xy_v2()

	struct input_event ts;
	int x1 = -1, y1 = -1;
	int x2, y2;
	int x_read = 0, y_read =1;
	// x1, y1, x2,y2
	
	//2, read coord
	while (1) 
		read(ts_fd, &ts, sizeof(ts));
		
		if (ts.type == EV_ABS && ts.code == ABS_X && x_read == 0)   
			if (x1 == -1) 
				x1 = ts.value;
			
			x2 = ts.value;
			x_read = 1;
			y_read = 0;
		
		
		if (ts.type == EV_ABS && ts.code == ABS_Y && y_read == 0) 
			if (y1 == -1) 
				y1 = ts.value;
			
			y2 = ts.value;
			x_read = 0;
			y_read = 1;
		
		
		if (x_read && y_read) 
			break;
		
		
		if (ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == KEY_RESERVED) 
			int num1 = x2-x1;
			int num2 = y2-y1;
			
			if (num1 > 0) 
				return 1;
			else if (num1 < 0) 
				return 2;
			
			
			if (num2 < 0) 
				return 3;
			else if (num2 > 0) 
				return 4;
			
			break;
		
	


/*
	fin_left:手指左划后棋子移动及合并的方式
*/
void fin_left()

	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value, save_zero;
	for(i = 0; i < 4; i++)
	
		value = 0;
		save_zero= 0;
		for(j = 0; j < 4 ; j++)
		
			if (array[i][j] == 0)
				continue;
			
			if (value == 0)
				value = array[i][j];
			else
			
				if (value == array[i][j])
				
					array[i][save_zero++] = value * 2;
					value = 0;
				 else 
					array[i][save_zero++] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		

		if (value != 0)
			array[i][save_zero] = value;

	
		

	//draw_matrix();
/*
	fin_right:手指上划后棋子移动及合并的方式
*/
void fin_right()

	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value;
	int save_zero;
	for (i = 0; i < 4; i++)
	
		value = 0;
		save_zero = 4 -1;
		for (j = 4 - 1; j >= 0 ; j--)
		
			if(array[i][j] == 0)
			
				continue;
			
			if(value == 0)
			
				value = array[i][j];
			
			else
			
				if(value == array[i][j])
				
					array[i][save_zero--] = 2 * value;
					value = 0;
				
				else
				
					array[i][save_zero--] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		
		if(value != 0)
		
			array[i][save_zero] = value;
		
	
	

/*
	fin_up:手指上划后棋子移动及合并的方式
*/
void fin_up()


	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value;
	int save_zero;

	for(j = 0; j < 4; j++)
	
		value = 0;
		save_zero= 0;
		for(i = 0; i < 4 ; i++)
		
		
			if(array[i][j] == 0)
			
				continue;
			
			if(value == 0)
			
				value = array[i][j];
			
			else
			
				if(value == array[i][j])
				
					array[save_zero++][j] =2 * value;
					value = 0;
				
				else
				
					array[save_zero++][j] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		
		if(value != 0)
		
			array[save_zero][j] = value;
		

	


	
	//draw_matrix();
/*
	fin_down:手指上划后棋子移动及合并的方式
*/
void fin_down()

	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value;
	int save_zero;
	
	for(j = 0; j < 4; j++)
	
		value = 0;
		save_zero = 4 - 1;
		for(i = 4 - 1; i >= 0 ; i--)
		
			if(array[i][j] == 0)
			
				continue;
			
			if(value == 0)
			
				value = array[i][j];
			
			else
			
				if(value == array[i][j])
				
					array[save_zero--][j] = 2 * value;
					value = 0;
				
				else
				
					array[save_zero--][j] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		
		if(value != 0)
		
			array[save_zero][j] = value;
		
		
	
	


/*
	change_matrix:根据手指滑动(direction),
		变换棋盘矩阵
*/
int change_matrix()

	
	int direction = get_finger_direction();
	if (direction == 1)
	
		fin_left();
	
	else if (direction == 2)
	
		fin_right();
	
	else if (direction == 3)
	
		fin_up();
	
	else
	
		fin_down();
	



/*
	lcd_draw_point:在屏幕坐为(x, y)这个点,填充color
	这个颜色值。
	@x: x轴坐标
	@y:y轴坐标
	@color:要填充的辨色值

	返回值:
		无返回值。

*/
void lcd_draw_point(int x, int y, int color)

	int *p = lcd_ptr;

	if (x >= 0 && x < 800 && y>=0 && y < 480)
	
		*(p +800*y + x) = color;
	



/*
	lcd_draw_dect: 在屏幕上画一个矩形,并且用
		color这种颜色填充该矩形。
	@x0: 该矩形的左上角的那个点x轴坐标
	@y0:该矩形的左上角的那个点y轴坐标
	@w:该矩形的宽
	@h:该矩形的高
	@color:该矩形要填充的辨色值

	返回值:
		无返回值。
		
*/
void lcd_draw_dect(int x0, int y0, int w, int h, int color)

	if (x0 < 0 || y0 < 0 || w < 0 || h <0)
		return;

	if ((x0 + w >800) || (y0+h) > 480)
	
		return;
	

	int x, y;

	for (y = y0; y < y0 + h; y++)
	
		for (x = x0; x < x0 + w; x++)
		
			lcd_draw_point(x, y  ,  color);
		
	



/*
	draw_bmp_byname:把一张bmp图片显示在屏幕上特定的位置
	@bmpfile:要显示的bmp图片的文件名
	@x0: 在屏幕上显示的左上角顶点的x轴坐标
	@y0: 在屏幕上显示的左上角顶点的y轴坐标
	@w: 位图宽度
	@h: 位图高度
	返回值:
		无返回值.
*/
void draw_bmp_byname(const char *bmpfile, int x0, int y0, int w, int h)

	int fd;
	int x, y;
	
	fd = open(bmpfile, O_RDONLY);
	if (fd == -1)
	
		perror("open bmpfile error:");
		return ;
	
	char bmpdata[w*h*3];	
	lseek(fd, 54, SEEK_SET);
	
	read(fd, bmpdata, w*h*3);

	close(fd);

	int i = 0;
	for (y = 0; y < h; y++)
	
		unsigned char r,g ,b;
		int color;

		for (x = 0; x < w; x++)
		
			b = bmpdata[i++];
			g = bmpdata[i++];
			r = bmpdata[i++];
			color = (r << 16) | (g << 8) | b;

			lcd_draw_point(x0+ x, y0 + (h -1 - y) ,color);
		
	





/*
	draw_matrix:把棋盘矩阵在屏幕上显示出来
*/
void draw_matrix()

	int i, j;
	for (i = 0; i < 4; i++)
	
		for (j = 0; j < 4;j++)
		
			int x0, y0;
			x0 = 185;//棋盘矩阵左上角那个点的x轴坐标
			y0 = 25;//棋盘矩阵左上角那个点的y轴坐标
			if (array[i][j] == 0)
			
				lcd_draw_dect(x0+j*110,  y0+i*110,  100, 100, 
						0xff8080);//如果此处元素的值为0,那么
								//就显示
			
			else
			
				int f_index = get_bmp_files_index(array[i][j]);
				draw_bmp_byname(bmp_files[f_index],
						x0+j*110,  y0+i*110,
						100,100);
			
		
	


/*
	init_matrix:初始化棋盘矩阵
			在任意x个位置,填充x个数字(2,4,8)
*/

void init_matrix()

	//规则x >= 1,x <= 3
	int x = (random() % 3) + 1;

	int i;

	/*
		step1:随机产生x个数字,并填充到棋盘矩阵中去
	*/

	for(i = 0; i < x; i++)
	
		int pos = (random() % rectangle_get_zero_num()) + 1;

		int s[] = 2, 4, 8, 2;
		int s_i = (random() % 3);

		rectangle_set_value(pos, s[s_i]);
	

	/*
		step 2: 绘制棋盘矩阵
	*/
	draw_matrix();



/*
	rand1_matrix:移动之后随机产生一个数字填充到
	任意一个0的位置上
*/
void rand_matrix()

	int pos = (random() % rectangle_get_zero_num()) + 1;

	int s[] = 2, 4, 8, 2;
	int s_i = (random() % 4);

	rectangle_set_value(pos, s[s_i]);
	draw_matrix();



/*
	get_finger_direction:获取手指在触摸屏上面的滑动方向
	返回值:
		MOVE_LEFT:手指向左移动
		MOVE_RIGHT:手指向右移动
		MOVE_UP:手指向上移动
		MOVE_DOWN:手指向下移动
*/
int get_finger_direction()

	int ret;
	int fd = open("/dev/input/event0", O_RDWR);
	if (fd == -1)
	
		perror("open event failed:");
		return -1;
	

	struct input_event ev;

	int  x1 = -1; //在滑动过程中第一个点的x轴坐标
	int x2; //在滑动过程中最后一个点的x轴坐标
	int y1 = -1;//在滑动过程中第一个点的y轴坐标
	int y2;//在滑动过程中最后一个点的y轴坐标

	while (1)
	
		ret = read(fd, &ev, sizeof(ev));
		if(ret != sizeof(ev))
		
			continue;
		
		
		if (ev.type == EV_ABS && ev.code == ABS_X)//是x轴坐标
		
			if (x1 == -1)//x1重来没有赋过值,那么肯定是第一个点
			
				x1 = ev.value;
			
			x2 = ev.value;
		
		if (ev.type == EV_ABS && ev.code == ABS_Y)//是y轴坐标
		
			if ( y1 == -1)//y1重来没有赋过值,那么肯定是第一个点
			
				y1 = ev.value;
			
			y2 = ev.value;
		


		// if (ev.type == EV_ABS && ev.code == ABS_PRESSURE//手指弹起,再计算滑动方向
		// 	&& ev.value == 0)//触摸屏压力值为0, press up
		if (ev.type == EV_KEY && ev.code == BTN_TOUCH)
		
			if(ev.value==0)
			
				int x_cz;//x轴的位移
				int y_cz;//y轴的位移
				int abs_x;
				int abs_y;
				x_cz = x2 - x1;
				y_cz = y2 - y1;
				abs_x = abs(x_cz);
				abs_y = abs(y_cz);
				
				if((x_cz > 30) && (abs_x > 2 * abs_y))
				
					close(fd);
					return 2;
				
				else if((x_cz < -30) && (abs_x > 2 * abs_y))
				
					close(fd);
					return 1;
				
				else if((y_cz > 30) && (abs_y > 2 * abs_x))
				
					close(fd);
					return 4;
				
				else if((y_cz < -30) && (abs_y > 2 * abs_x))
				
					close(fd);
					return 3;
					
				else	
				
					x1 = y1 = -1;
					continue;
				

				break;

			
		
	


	close(fd);



/*
	move_judge:判断是否还能移动
	return value:
		1 game over
		0 continue
*/
int move_judge()

	int i, j;
	if(rectangle_get_zero_num() != 0)
	
		return 0;
	

	for(i = 0; i < 4; i++)
	
		for(j = 0; j < 4 ; j++)
		
			if (j != 4 -1)
			
				if (array[i][j] == array[i][j+1])
				
					return 0;
				
			

			if (i != 4 - 1)
			
				if (array[i][j] == array[i+1][j])
				
					return 0;
				
			
		
	
	
	
	return 1;




int main()


	/*step 1: 打开屏幕*/
	lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	
		perror("open fb0 failed:");
		return -1;
	
	
	/*step 2: mmap*/
	lcd_ptr = mmap(
			NULL, //第一个参数,为映射后的内存地址,
				 //为NULL,表示让操作系统自行分配
				 
			800*480*4, //第二个参数,为映射的长度。

			PROT_WRITE, //第三个参数,为映射内存区域的权限


			MAP_SHARED, //第四个参数,为映射标志,shared

			lcd_fd, //第五个参数,为文件描述符,表示您要
				//映射哪个文件

			0 //第六个参数为偏移量,表示您要从文件的
				//哪个位置开始映射
	
	);


	lcd_draw_dect(0, 0, 800, 480, 0x0080ff);//清屏
	
	srandom( time(NULL) ); //设置随机数种子,种子一样,产生的
						//随机数是一样的

	init_matrix();


	while (game_over == 0) //游戏没结束
	
		//用来保存原来的矩阵值
		int matrix_v1[4][4];
		int i, j, flag = 0;
		for (i = 0; i < 4; ++i)
		
			for (j = 0; j < 4; ++j)
			
				matrix_v1[i][j] = array[i][j];
			
		
		/*
			step 1: 变换矩阵
		*/
		change_matrix();

		for (i = 0; i < 4; ++i)
		
			for (j = 0; j < 4; ++j)
			
				if (matrix_v1[i][j] != array[i][j])
				
					flag = 1;
					i = j = 4;
				
			
		
		if (flag)
		
			rand_matrix();
			draw_matrix();
		 
		else 
		
			draw_matrix();
		
		game_over = move_judge();
	
	
	printf("Game Over~~");
	munmap(lcd_ptr, 800*480*4);
	close(lcd_fd);

电子相册+2048小游戏

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include<linux/fb.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include<string.h>


int lcd_fd, ts_fd;
int *lcd_ptr;
int game_over;
int get_finger_direction();

struct bmp_header 		//14
	unsigned char type[2];
	unsigned long size;
	unsigned short reserverd1;
	unsigned short reserverd2;
	unsigned long offbit;
__attribute__((packed));		//字节对齐

struct bmp_info 	//40
	unsigned int size;
	unsigned int width;
	unsigned int height;
	unsigned short planes;
	unsigned short bitcount;
	unsigned int bitcompression;
	unsigned int sizeimg;
	unsigned int xpelspermeter;
	unsigned int ypelspermeter;
	unsigned int biclrused;
	unsigned int important;
__attribute__((packed));		//字节对齐

int dev_init()

	//1,lcd device init
	lcd_fd = open("/dev/fb0", O_RDWR);

	if (lcd_fd == -1) 
		printf("open lcd device failed!\\n");
		return -1;
	

	//建立映射(走到镜子)
	lcd_ptr = mmap(NULL,		//内存映射的地址,默认填NULL,由系统来分配
			800*480*4,//内存映射区的大小
			PROT_READ | PROT_WRITE,//操作标志
			MAP_SHARED,//共享标志
			lcd_fd,	//将要进行映射的文件的别名
			0		//偏移量
		      );

	if (lcd_ptr == MAP_FAILED) 
		printf("mmap failed!\\n");
		return -2;
	

	ts_fd = open("/dev/input/event0", O_RDONLY);

	if (ts_fd == -1) 
		printf("open lcd device failed!\\n");
		return -3;
	

	return 0;


void dev_uninit()

	munmap(lcd_ptr, 800*480*4);
	close(lcd_fd);
	close(ts_fd);


int show_bmp(int x, int y, const char* pathname)

	//bmp file
	int bmp_fd = open(pathname, O_RDWR);

	if (bmp_fd == -1) 
		printf("open bmp file failed!\\n");
		return -1;
	

	struct bmp_header b_header;
	struct bmp_info b_info;

	read(bmp_fd, &b_header, 14);
	read(bmp_fd, &b_info, 40);

	int w, h;
	w = b_info.width;
	h = b_info.height;

	//b)	读取图片颜色数据
	char rgb_buf[w*h*3];
	int tmp_buf[w*h];
	int lcd_buf[800*480];

	read(bmp_fd, rgb_buf, w*h*3);

	// 24 --- > 32

	int i, j;
	int color;
	for (i = 0; i < w*h; i++) 
		/*
		   color = rgb_buf[0];		//b
		   color = (rgb_buf[1] << 8);	//g
		   color = (rgb_buf[2] << 16);	//r
		   lcd_buf[0] = color;

		   color = rgb_buf[3];		//b
		   color = (rgb_buf[4] << 8);	//g
		   color = (rgb_buf[5] << 16);	//r
		   lcd_buf[1] = color;

		 */
		color = rgb_buf[3*i];		//b
		color |= (rgb_buf[3*i+1] << 8);	//g
		color |= (rgb_buf[3*i+2] << 16);	//r
		tmp_buf[i] = color;

	

	// up down
	for (i = 0; i < h; i++) 
		for (j = 0; j < w; j++) 
			lcd_ptr[(i+y)*800+(j+x)] = tmp_buf[(h-1-i)*w+j];
		
	

	//c)	将图片颜色数据写入到lcd屏幕
	//write(lcd_fd, lcd_buf, 800*480*4);

	close(bmp_fd);

	return 0;


int get_xy(int *x, int *y)

	struct input_event ts;
	int x_read = 0, y_read =1;
	// x1, y1, x2,y2

	//2, read coord
	while (1) 
		read(ts_fd, &ts, sizeof(ts));

		if (ts.type == EV_ABS && ts.code == ABS_X && x_read == 0)   
			*x = ts.value;
			x_read = 1;
			y_read = 0;
		

		if (ts.type == EV_ABS && ts.code == ABS_Y && y_read == 0) 
			*y = ts.value;
			x_read = 0;
			y_read = 1;
		

		if (ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == KEY_RESERVED) 
			printf("手指已经离开\\n");
			break;
		
	

	return 0;


int log_on()

	
	int xing_x[6] = 175,255,325,395,475,545;
	
	char number[7] = 0;
	char vc[7] = 0;
	
	//获取随机数种子
	srandom(time(NULL));
	
	show_bmp(0, 0, "/pic/bmp/vc_login.bmp");
	
	int i;
	bzero(number, 6);
	for (i = 0; i < 6; i++) 
		number[i] = (random()%10)+48;
		printf("%d ", number[i]);
	
	
	printf("\\n");

	number[7] = '\\0';

	printf("number : %s\\n", number);

	int x, y;
	int j = 0;

	while (1) 
		get_xy(&x, &y);
		if (y > 160 && y <= 275 && j < 6) 
			
			//1 2 3
			if (x > 170 && x < 385) 
				vc[j] = '1';
				// /pic/bmp/
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("111\\n");
			else if (x > 390 && x < 605) 
				vc[j] = '2';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("222\\n");
			else if (x > 610 && x < 800) 
				vc[j] = '3';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("333\\n");
			
		else if (y > 280 && y <= 395 && j < 6) 
			
			//4 5 6
			if (x > 170 && x < 385) 
				vc[j] = '4';
				// /pic/bmp/
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("444\\n");
			else if (x > 390 && x < 605) 
				vc[j] = '5';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("555\\n");
			else if (x > 610 && x < 800) 
				vc[j] = '6';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("666\\n");
			
			
		else if (y > 400 && y <= 465 && j < 6) 
			
			//7 8 9
			if (x > 170 && x < 385) 
				vc[j] = '7';
				// /pic/bmp/
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("777\\n");
			else if (x > 390 && x < 605) 
				vc[j] = '8';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("888\\n");
			else if (x > 610 && x < 800) 
				vc[j] = '9';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("999\\n");
			
		else if (y > 470 && y <= 615) 
			if (x > 170 && x < 385 && j > 0) 
				j--;
				vc[j] = '0';
				show_bmp(xing_x[j], 62, "/pic/bmp/white.bmp");
				printf("delete!\\n");
			else if (x > 390 && x < 605 && j < 6) 
				vc[j] = '0';
				show_bmp(xing_x[j], 62, "/pic/bmp/star.bmp");
				j++;
				printf("000\\n");
			else if (x > 610 && x < 800) 
				vc[7] = '\\0';
				printf("%s\\n", vc);
				if (strncmp(number, vc, 6) == 0) 
					show_bmp(200, 120, "/pic/bmp/correct.bmp");
					sleep(1);
					break;
				else 
					show_bmp(200, 120, "/pic/bmp/error.bmp");
					sleep(1);
					j = 0;
					bzero(vc, 6);
					/* for (i = 0; i < 6; i++) 
						show_bmp(xing_x[i], 62, "/pic/bmp/white.bmp");
					 */
					show_bmp(0, 0, "/pic/bmp/vc_login.bmp");
					continue;
				
			
		
	




int show_pic(void)

	//1, device init
	int rt = dev_init();

	if (rt != 0) 
		printf("rt : %d\\n", rt);
		return -1;
	

	//2, oper

	//gif
	int i;

	char buf[1024] = 0;	//bzero

	for (i = 0; i < 10; i++) 
		sprintf(buf, "/pic/gif/%d.bmp", i);
		show_bmp(0, 0, buf);
		usleep(100000);
	

	//log on
	log_on();

	
	//main

	//3, rmmod to device
	dev_uninit();

	return 0;



//数组初始化,将所有的图片保存在一个数组中
const char *bmp_files[] = 
	"/pic/bmp/digit_2.bmp", "/pic/bmp/digit_4.bmp",
	"/pic/bmp/digit_8.bmp", "/pic/bmp/digit_16.bmp",
	"/pic/bmp/digit_32.bmp", "/pic/bmp/digit_64.bmp",
	"/pic/bmp/digit_128.bmp", "/pic/bmp/digit_256.bmp",
	"/pic/bmp/digit_512.bmp", "/pic/bmp/digit_1024.bmp",
	"/pic/bmp/digit_2048.bmp", "/pic/bmp/digit_4096.bmp",
	"/pic/bmp/digit_8192.bmp", "/pic/bmp/digit_16384.bmp",
	"/pic/bmp/digit_32768.bmp", "/pic/bmp/digit_65536.bmp"
;

//棋盘矩阵的初始化
int array[4][4] = 0;

//根据要显示的数字来返回对应的文件名的下标
int get_bmp_files_index(int x)

	if (x == 2) 
		return 0;
	else if (x == 4) 
		return 1;
	else if (x == 8) 
		return 2;
	else if (x == 16) 
		return 3;
	else if (x == 32) 
		return 4;
	else if (x == 64) 
		return 5;
	else if (x == 128) 
		return 6;
	else if (x == 256) 
		return 7;
	else if (x == 512) 
		return 8;
	else if (x == 1024) 
		return 9;
	else if (x == 2048) 
		return 10;
	else if (x == 4096) 
		return 11;
	else if (x == 8192) 
		return 12;
	else if (x == 16384) 
		return 13;
	else if (x == 32768) 
		return 14;
	else if (x == 65536) 
		return 15;
	
	
	return -1;


//求棋盘矩阵里面有多少个0
int rectangle_get_zero_num()

	int i, j, count = 0;
	for (i = 0; i < 4; i++) 
		for (j = 0; j < 4; j++) 
			if (array[i][j] == 0) 
				count++;
			
		
	
	
	return count;


int rectangle_set_value(int z, int value)

	int i, j, count = 0;
	for (i = 0; i < 4; i++) 
		for (j = 0; j < 4; j++) 
				if (array[i][j] == 0) 
					count++;
					if (count == z) 
						array[i][j] = value;
						return 0;
					
				
				
		
	


//触摸屏滑屏算法实现
int get_xy_v2()

	struct input_event ts;
	int x1 = -1, y1 = -1;
	int x2, y2;
	int x_read = 0, y_read =1;
	// x1, y1, x2,y2
	
	//2, read coord
	while (1) 
		read(ts_fd, &ts, sizeof(ts));
		
		if (ts.type == EV_ABS && ts.code == ABS_X && x_read == 0)   
			if (x1 == -1) 
				x1 = ts.value;
			
			x2 = ts.value;
			x_read = 1;
			y_read = 0;
		
		
		if (ts.type == EV_ABS && ts.code == ABS_Y && y_read == 0) 
			if (y1 == -1) 
				y1 = ts.value;
			
			y2 = ts.value;
			x_read = 0;
			y_read = 1;
		
		
		if (x_read && y_read) 
			break;
		
		
		if (ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == KEY_RESERVED) 
			int num1 = x2-x1;
			int num2 = y2-y1;
			
			if (num1 > 0) 
				return 1;
			else if (num1 < 0) 
				return 2;
			
			
			if (num2 < 0) 
				return 3;
			else if (num2 > 0) 
				return 4;
			
			break;
		
	


/*
	fin_left:手指左划后棋子移动及合并的方式
*/
void fin_left()

	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value, save_zero;
	for(i = 0; i < 4; i++)
	
		value = 0;
		save_zero= 0;
		for(j = 0; j < 4 ; j++)
		
			if (array[i][j] == 0)
				continue;
			
			if (value == 0)
				value = array[i][j];
			else
			
				if (value == array[i][j])
				
					array[i][save_zero++] = value * 2;
					value = 0;
				 else 
					array[i][save_zero++] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		

		if (value != 0)
			array[i][save_zero] = value;

	
		

	//draw_matrix();
/*
	fin_right:手指上划后棋子移动及合并的方式
*/
void fin_right()

	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value;
	int save_zero;
	for (i = 0; i < 4; i++)
	
		value = 0;
		save_zero = 4 -1;
		for (j = 4 - 1; j >= 0 ; j--)
		
			if(array[i][j] == 0)
			
				continue;
			
			if(value == 0)
			
				value = array[i][j];
			
			else
			
				if(value == array[i][j])
				
					array[i][save_zero--] = 2 * value;
					value = 0;
				
				else
				
					array[i][save_zero--] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		
		if(value != 0)
		
			array[i][save_zero] = value;
		
	
	

/*
	fin_up:手指上划后棋子移动及合并的方式
*/
void fin_up()


	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value;
	int save_zero;

	for(j = 0; j < 4; j++)
	
		value = 0;
		save_zero= 0;
		for(i = 0; i < 4 ; i++)
		
		
			if(array[i][j] == 0)
			
				continue;
			
			if(value == 0)
			
				value = array[i][j];
			
			else
			
				if(value == array[i][j])
				
					array[save_zero++][j] =2 * value;
					value = 0;
				
				else
				
					array[save_zero++][j] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		
		if(value != 0)
		
			array[save_zero][j] = value;
		

	


	
	//draw_matrix();
/*
	fin_down:手指上划后棋子移动及合并的方式
*/
void fin_down()

	int i, j;//i为矩阵行下标,j为矩阵列下标
	int value;
	int save_zero;
	
	for(j = 0; j < 4; j++)
	
		value = 0;
		save_zero = 4 - 1;
		for(i = 4 - 1; i >= 0 ; i--)
		
			if(array[i][j] == 0)
			
				continue;
			
			if(value == 0)
			
				value = array[i][j];
			
			else
			
				if(value == array[i][j])
				
					array[save_zero--][j] = 2 * value;
					value = 0;
				
				else
				
					array[save_zero--][j] = value;
					value = array[i][j];
				
			
			array[i][j] = 0;
		
		if(value != 0)
		
			array[save_zero][j] = value;
		
		
	
	


/*
	change_matrix:根据手指滑动(direction),
		变换棋盘矩阵
*/
int change_matrix()

	
	int direction = get_finger_direction();
	if (direction == 1)
	
		fin_left();
	
	else if (direction == 2)
	
		fin_right();
	
	else if (direction == 3)
	
		fin_up();
	
	else
	
		fin_down();
	



/*
	lcd_draw_point:在屏幕坐为(x, y)这个点,填充color
	这个颜色值。
	@x: x轴坐标
	@y:y轴坐标
	@color:要填充的辨色值

	返回值:
		无返回值。

*/
void lcd_draw_point(int x, int y, int color)

	int *p = lcd_ptr;

	if (x >= 0 && x < 800 && y>=0 && y < 480)
	
		*(p +800*y + x) = color;
	



/*
	lcd_draw_dect: 在屏幕上画一个矩形,并且用
		color这种颜色填充该矩形。
	@x0: 该矩形的左上角的那个点x轴坐标
	@y0:该矩形的左上角的那个点y轴坐标
	@w:该矩形的宽
	@h:该矩形的高
	@color:该矩形要填充的辨色值

	返回值:
		无返回值。
		
*/
void lcd_draw_dect(int x0, int y0, int w, int h, int color)

	if (x0 < 0 || y0 < 0 || w < 0 || h <0)
		return;

	if ((x0 + w >800) || (y0+h) > 480)
	
		return;
	

	int x, y;

	for (y = y0; y < y0 + h; y++)
	
		for (x = x0; x < x0 + w; x++)
		
			lcd_draw_point(x, y  ,  color);
		
	



/*
	draw_bmp_byname:把一张bmp图片显示在屏幕上特定的位置
	@bmpfile:要显示的bmp图片的文件名
	@x0: 在屏幕上显示的左上角顶点的x轴坐标
	@y0: 在屏幕上显示的左上角顶点的y轴坐标
	@w: 位图宽度
	@h: 位图高度
	返回值:
		无返回值.
*/
void draw_bmp_byname(const char *bmpfile, int x0, int y0, int w, int h)

	int fd;
	int x, y;
	
	fd = open(bmpfile, O_RDONLY);
	if (fd == -1)
	
		perror("open bmpfile error:");
		return ;
	
	char bmpdata[w*h*3];	
	lseek(fd, 54, SEEK_SET);
	
	read(fd, bmpdata, w*h*3);

	close(fd);

	int i = 0;
	for (y = 0; y < h; y++)
	
		unsigned char r,g ,b;
		int color;

		for (x = 0; x < w; x++)
		
			b = bmpdata[i++];
			g = bmpdata[i++];
			r = bmpdata[i++];
			color = (r << 16) | (g << 8) | b;

			lcd_draw_point(x0+ x, y0 + (h -1 - y) ,color);
		
	





/*
	draw_matrix:把棋盘矩阵在屏幕上显示出来
*/
void draw_matrix()

	int i, j;
	for (i = 0; i < 4; i++)
	
		for (j = 0; j < 4;j++)
		
			int x0, y0;
			x0 = 185;//棋盘矩阵左上角那个点的x轴坐标
			y0 = 25;//棋盘矩阵左上角那个点的y轴坐标
			if (array[i][j] == 0)
			
				lcd_draw_dect(x0+j*110,  y0+i*110,  100, 100, 
						0xff8080);//如果此处元素的值为0,那么
								//就显示
			
			else
			
				int f_index = get_bmp_files_index(array[i][j]);
				draw_bmp_byname(bmp_files[f_index],
						x0+j*110,  y0+i*110,
						100,100);
			
		
	


/*
	init_matrix:初始化棋盘矩阵
			在任意x个位置,填充x个数字(2,4,8)
*/

void init_matrix()

	//规则x >= 1,x <= 3
	int x = (random() % 3) + 1;

	int i;

	/*
		step1:随机产生x个数字,并填充到棋盘矩阵中去
	*/

	for(i = 0; i < x; i++)
	
		int pos = (random() % rectangle_get_zero_num()) + 1;

		int s[] = 2, 4, 8, 2;
		int s_i = (random() % 3);

		rectangle_set_value(pos, s[s_i]);
	

	/*
		step 2: 绘制棋盘矩阵
	*/
	draw_matrix();



/

以上是关于粤嵌GEC6818,基于LVGL和mplayer的音视频播放器的主要内容,如果未能解决你的问题,请参考以下文章

粤嵌GEC6818-学习笔记2-屏幕相关及音频播放

粤嵌gec6818开发板LED屏幕上画图(数组与内存映射的采用)换图片 电子相册 实现识别触摸坐标的识别等项目

粤嵌gec6818LED屏幕上画图 太极图 图片显示 电子相册 2048小游戏 实现识别触摸坐标的识别 电子自助点餐设计等项目

小学期Deadline之GEC6818点奶茶系统

小学期Deadline之GEC6818点奶茶系统

GEC6818开发板JPG图像显示,科大讯飞离线语音识别包Linux_aitalk_exp1227_1398d7c6运行demo程序,开发板实现录音