#include "common.h"
#include "bmp.h"
int g_lcd_width = 0;
int g_lcd_height = 0;
int g_lcd_bpp = 0;
/*
get_bmpfiles_index:根据你要显示的数字(2,4,8,16,...)
返回你对应的文件名的下标
返回值:
返回 x对应的文件名在数组bmpfiles的下标
*/
int get_bmpfiles_index(int x)
{
int exp;
for(exp=0; x!=0; x >>= 1, exp++);
return exp-2;
}
//棋盘矩阵
int matrix[BOARDSIZE][BOARDSIZE] =
{
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
};
/*
get_zero_num:求棋盘矩阵里面有多少个0
返回值:
返回棋盘矩阵中0的个数
*/
int get_zero_num(void)
{
int z = 0;//棋盘矩阵中元素为0的个数
int i, j;
//BOARDSIZE = 4,整个棋盘大小为BOARDSIZE*BOARDSIZE
for (i = 0; i < BOARDSIZE; i++)
{
for (j = 0; j < BOARDSIZE; j++)
{
if (matrix[i][j] == 0)
{
z++;
}
}
}
return z;
}
/*
set_matrix:给棋盘矩阵第z个0的位置,填充一个
值s
*/
void set_matrix(int z, int s)
{
int i, j;
int k = 0 ;//0的个数
for (i = 0; i < BOARDSIZE ;i++)
{
for (j = 0; j < BOARDSIZE; j++)
{
if (matrix[i][j] == 0)
{
k++;
if (k == z)
{
matrix[i][j] = s;
return ;
}
}
}
}
}
/*
lcd_draw_point:在屏幕坐为(x, y)这个点,填充color
这个颜色值。
@x: x轴坐标
@y: y轴坐标
@color: 要填充的辨色值
返回值:
无返回值。
*/
void lcd_draw_point(int x, int y, int color)
{
int *p = plcd;
if (x >= 0 && x < g_lcd_width && y>=0 && y < g_lcd_height)
{
*(p + g_lcd_width *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 > g_lcd_width) || (y0+h) > g_lcd_height)
{
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:把一张bmp图片显示在屏幕上特定的位置
@bmpfile:要显示的bmp图片的文件名
@x0: 在屏幕上显示的左上角顶点的x轴坐标
@y0: 在屏幕上显示的左上角顶点的y轴坐标
返回值:
无返回值.
*/
void draw_bmp(const char *bmpfile, int x0, int y0)
{
int fd;
int x, y;
fd = open(bmpfile, O_RDONLY);
if (fd == -1)
{
perror("open bmpfile error:");
return ;
}
struct header head;
struct info info;
read(fd, &head, sizeof(head));
read(fd, &info, sizeof(info));
char *bmpdata = calloc(1, head.size-head.offbytes);
read(fd, bmpdata, info.width * info.height * info.bit_count/8);
close(fd);
int i = 0;
for (y = 0; y < info.height; y++)
{
unsigned char r,g ,b;
int color;
for (x = 0; x < info.width; x++)
{
b = bmpdata[i++];
g = bmpdata[i++];
r = bmpdata[i++];
color = (r << 16) | (g << 8) | b;
lcd_draw_point(x0+ x, y0 + (info.height -1 - y) ,color);
}
}
free(bmpdata);
}
/*
draw_matrix:把棋盘矩阵在屏幕上显示出来
*/
void draw_matrix(void)
{
int i, j;
for (i = 0; i < BOARDSIZE; i++)
{
for (j = 0; j < BOARDSIZE;j++)
{
int x0, y0;
x0 = 185;//棋盘矩阵左上角那个点的x轴坐标
y0 = 25;//棋盘矩阵左上角那个点的y轴坐标
if (matrix[i][j] == 0)
{
lcd_draw_dect(x0+j*110, y0+i*110,
100 , 100,
0xb4eeb4);//如果此处元素的值为0,那么
//就显示
}
else
{
int f_index = get_bmpfiles_index(matrix[i][j]);
draw_bmp(bmpfiles[f_index],
x0+j*110, y0+i*110);
}
}
}
}
/*
init_matrix:初始化棋盘矩阵
在任意x个位置,填充x个数字(2,4,8)
*/
void init_matrix(void)
{
//规则x >= 1,x <= 3
int x = (random() % 3) + 1;
int i;
/*
step1:随机产生x个数字,并填充到棋盘矩阵中去
*/
for(i = 0; i < x; i++)
{
int pos = (random() % get_zero_num()) + 1;
int s[] = {2, 4, 4, 2};
int s_i = (random() % 3);
set_matrix(pos, s[s_i]);
}
/*
step 2: 绘制棋盘矩阵
*/
draw_matrix();
}
/*
rand1_matrix:移动之后随机产生一个数字填充到
任意一个0的位置上
*/
void rand_matrix()
{
int pos = (random() % get_zero_num()) + 1;
int s[] = {2, 4, 8, 2};
int s_i = (random() % 4);
set_matrix(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_RDONLY);
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_KEY && ev.code == BTN_TOUCH //手指弹起,再计算滑动方向
&& ev.value == 0)//触摸屏压力值为0, press up
{
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 MOVE_RIGHT;
}
else if((x_cz < -30) && (abs_x > 2 * abs_y))
{
close(fd);
return MOVE_LEFT;
}
else if((y_cz > 30) && (abs_y > 2 * abs_x))
{
close(fd);
return MOVE_UP;
}
else if((y_cz < -30) && (abs_y > 2 * abs_x))
{
close(fd);
return MOVE_DOWN;
}
else
{
x1 = y1 = -1;
continue;
}
}
}
close(fd);
}
/*
fin_left:手指左划后棋子移动及合并的方式
*/
void fin_left()
{
int i, j;//i为矩阵行下标,j为矩阵列下标
int value, save_zero;
for(i = 0; i < BOARDSIZE; i++)
{
value = 0;
save_zero= 0;
for(j = 0; j < BOARDSIZE ; j++)
{
if (matrix[i][j] == 0)
continue;
if (value == 0)
value = matrix[i][j];
else
{
if (value == matrix[i][j])
{
matrix[i][save_zero++] = value * 2;
value = 0;
} else {
matrix[i][save_zero++] = value;
value = matrix[i][j];
}
}
matrix[i][j] = 0;
}
if (value != 0)
matrix[i][save_zero] = value;
}
}
/*
手指上划后棋子移动及合并的方式
*/
void fin_right()
{
}
/*
fin_up:手指上划后棋子移动及合并的方式
*/
void fin_up()
{
}
//draw_matrix();
/*
fin_down:手指上划后棋子移动及合并的方式
*/
void fin_down()
{
}
/*
判断是否还能移动
*/
bool is_game_over(void)
{
int i, j;
if(get_zero_num() != 0)
{
return false;
}
for(i = 0; i < BOARDSIZE; i++)
{
for(j = 0; j < BOARDSIZE ; j++)
{
if (j != BOARDSIZE -1)
{
if (matrix[i][j] == matrix[i][j+1])
{
return false;
}
}