基于51的俄罗斯方块

//variable.h 定义该程序用到的全局变量

#ifndef _VARIABLE_H
#define _VARIABLE_H

#define GAME_BOARD_WIDTH     50
#define GAME_BOARD_HEIGHT     64

#define PIXEL_PER_CUBE_X    5//4
#define PIXEL_PER_CUBE_Y    4//3

#define NEXT_CUBES_SHOW_POS_X 11
#define NEXT_CUBES_SHOW_POS_Y 9

#define CUBE_COUNT_X        10
#define CUBE_COUNT_Y        16

#define WALL_LOC            (GAME_BOARD_WIDTH - 1)

//command
#define MOVE_LEFT            0x80
#define MOVE_RIGHT            0x40
#define MOVE_DOWN            0x20
#define ROTATION            0x10
#define NO_ACTION            0x01

#define PAUSE                0x02
#define QUIT                0x04
#define CONFIRM                0x08

//level
#define LEVEL0            40            //2s
#define LEVEL1            20            //1s
#define LEVEL2            10            //0.5s
#define LEVEL3            7            //
#define LEVEL4            5            //
#define LEVEL5            3            //

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

unsigned char command = NO_ACTION;
unsigned char game_score    = 0;
unsigned char game_score_str[4] = {0};
unsigned char game_score1     = 0;
unsigned char game_score2    = 0;
unsigned char game_score3    = 0;

xdata unsigned int game_board_cube[16] = {0};
xdata unsigned int snake_game_board_cube[16] = {0};

xdata unsigned char highest_cube_per_column[CUBE_COUNT_X] = {0};

unsigned char game_level = LEVEL5;
unsigned char real_game_level = 2;
typedef struct _Cubes
{
    unsigned char x1, y1;
    unsigned char x2, y2;
    unsigned char x3, y3;
    unsigned char x4, y4;
    unsigned char cube_type;
    unsigned char signature;
}Cubes;

Cubes prev_cubes = {0};
Cubes curr_cubes = {0};
Cubes next_cubes = {0};

#endif

//main.c 主函数
//#include "t6963.c"
#include "variable.h"
#include "teric.c"
//产生随机数
//#define RAND_MAX 32767

unsigned int time = 0;
bit start_count = 1;

/*
* 功  能:定时器0的初始化
* 参  数:无
* 返回值:无
*/
void Timer_Init(void)
{
    EA = 0;
    TMOD=0x11;                 //采用的是定时器0,工作与模式1
    TH0=(65536-46080)/256;    //每隔50ms发起一次中断。
    TL0=(65536-46080)%256;    //50000*11.0592/12 

    TR0=1;                     //启用定时器
    ET0=1;                     //开定时器0中断

    TR1=1;
    ET1=1;

    EA=1;                     //开总中断
}

void Timer0_Stop(void)
{
    TR0=0;                     //启用定时器
    ET0=0;                     //开定时器0中断
//    EA=0;                     //开总中断
}

/*
* 功  能:定时器0的中断处理
* 参  数:无
* 返回值:无
*/
void Time0_Int() interrupt 1
{
    TH0 = (65536-46080) / 256;
    TL0 = (65536-46080) % 256;

    if (start_count == 1)
        time ++;
    if (time == game_level)
    {
        Timer0_Stop();
    }
    //    t++;
}

/*
* 功  能:定时器1的中断处理
* 参  数:无
* 返回值:无
*/
void Time1_Int() interrupt 3
{
    TH1 = (65536-46080) / 256;
    TL1 = (65536-46080) % 256;

//    if (start_count == 1)
//        time ++;
//    if (time == game_level)
//    {
//        Timer0_Stop();
//    }
    //    t++;
}

#define KEY_DATA        XBYTE[0x0F700]        // 数据口
void KeyDown()
{
    //写行
    uchar sel_row;
    uchar sel_col;
    sel_row = 0x0FE;
    KEY_DATA = sel_row;
    sel_col = KEY_DATA & 0x0f0;

    if (sel_col == 0xE0)
    {
    //    LCM_print_ram(9, 1, "LEFT");

        command = MOVE_LEFT;
        return;
    //    move_left = MOVE_LEFT;
     //    move_right = NO_ACTION;
    //    move_down = NO_ACTION;
    //    rotation = NO_ACTION;
    }
//    else if (sel_col == 0xD0)
//    {
//        LCM_print_ram(9, 1, "8");
//    }
//    else if (sel_col == 0xB0)
//    {
//        LCM_print_ram(9, 1, "4");
//    }
    else if (sel_col == 0xB0)
    {
    //    LCM_print_ram(9, 1, "CONFIRM");
        command = CONFIRM;
        return;
    }
    else if (sel_col == 0x70)
    {
        LCM_print_ram(3,7,"Level 0");
        game_level = LEVEL0;
        return;
    }

    sel_row = 0x0FD;

    KEY_DATA = sel_row;
    sel_col = KEY_DATA & 0x0f0;

    if (sel_col == 0xE0)
    {
    //    LCM_print_ram(9, 1, "DOWN");
        command = MOVE_DOWN;
        return;
    }
    else if (sel_col == 0xD0)
    {
        command = ROTATION;
        return;
    }
    else if (sel_col == 0xB0)
    {
    //    LCM_print_ram(9, 1, "PAUSE");
        command = PAUSE;
        return;
    //    command = CANCLE;
    }
    else if (sel_col == 0x70)
    {
        LCM_print_ram(3,7,"Level 1");
        game_level = LEVEL1;
        return;
    }

    sel_row = 0x0FB;
    KEY_DATA = sel_row;
    sel_col = KEY_DATA & 0x0f0;

    if (sel_col == 0xE0)
    {
        command = MOVE_RIGHT;
        return;
    }

    else if (sel_col == 0xB0)
    {
        LCM_print_ram(9, 1, "QUIT");
        command = QUIT;
        return;
    }

    else if (sel_col == 0x70)
    {
        LCM_print_ram(3,7,"Level 2");
        game_level = LEVEL2;
        return;
    }
}

void main()
{
//    uchar x1, x2, x3, x4, y1, y2, y3, y4;
    //uchar x, y;
    bit which_buff = 0;
//    uint tmp = 0;
    uchar cube_type = 15;
    uchar next_cube_type = 0;
    bit flag = 0;
    bit full_row_flag = 0;
    bit game_over_flag = 0;
    uchar rand_num;

    LCM_init();
    LCM_clear_text();
    LCM_clear_graph1();
    LCM_clear_ram();
//    game_level = LEVEL5;

label_start_game:
    GameMainScreen(command, game_over_flag);
    for (;;)
    {
        KeyDown();
        //默认等级
        if (command == CONFIRM)
        {
            LCM_clear_text();
            LCM_clear_graph1();
            LCM_clear_ram();
            command = NO_ACTION;
            PrintMyInfo();
            game_level = LEVEL5;
            Timer_Init();

            goto label_start_play_game;
        }
        //选择等级
        else if (game_level == LEVEL0 || game_level == LEVEL1 || game_level == LEVEL2)
        {
            LCM_clear_text();
            LCM_clear_graph1();
            LCM_clear_ram();
            if(game_level == LEVEL0)
            {
                LCM_print_ram(3,5,"You Select");
                LCM_print_ram(3,6,"Level 0");
            }
            else if (game_level == LEVEL1)
            {
                LCM_print_ram(3,5,"You Select");
                LCM_print_ram(3,6,"Level 1");
            }
            else if(game_level == LEVEL2)
            {
                LCM_print_ram(3,5,"You Select");
                LCM_print_ram(3,6,"Level 2");
            }
            DelayMs(500);
            command = NO_ACTION;
            LCM_clear_text();
            PrintMyInfo();
            Timer_Init();
            goto label_start_play_game;
        }
    }

    while(1);

label_start_play_game:
//    command = NO_ACTION;
    DrawWall();
    //游戏开始之前检测每个柱子的最大高度
    GetHightCubePerColumn();
    //随机生成一个cubes
    rand_num = TL1 % 18;
    cube_type = rand_num;
    curr_cubes = InitCubes(cube_type);
    //在game_board_cubes置1
    SetCubes(game_board_cube, 1);
    //绘制cubes
    DrawTericCubes(curr_cubes);
//
//    DrawNums(SCORE_NUM_POS_X, SCORE_NUM_POS_Y - NUM_HEIGHT, game_level);
    DrawScore();
    //提示下一个cubes
    rand_num = TL1 % 18;
    next_cube_type = rand_num;
    next_cubes = InitCubes(next_cube_type);
    ShowNextCubes();

label_play_game:
    for(;;)
    {

        KeyDown();
        if (command == PAUSE)
        {
            command = NO_ACTION;
            goto label_stop_game;
        }

        if (command == QUIT)
        {
            command = NO_ACTION;
            goto label_quit_game;
        }
        rand_num = TL1 % 18;
        //每隔一定的时间显示界面
        if (time == game_level)
        {
            start_count = 0;

            //判断当前cubes是否能够再降落下来
            if(curr_cubes.y1 < highest_cube_per_column[curr_cubes.x1] &&
               curr_cubes.y2 < highest_cube_per_column[curr_cubes.x2] &&
               curr_cubes.y3 < highest_cube_per_column[curr_cubes.x3] &&
               curr_cubes.y4 < highest_cube_per_column[curr_cubes.x4])
            {
                //保存上一次的cubes状态,
                //由于在cubes下降过程中,要将之前的cubes清除
                //所以通过保存上一次的cubes可以实现对先前cubes的清除
                prev_cubes = curr_cubes;
                //在game_board_cubes中间先前的cubes位置置0
            //    ResetPrevCubes();
                SetCubes(game_board_cube, 0);

                //绘制之前的cubes,实际上是清除cubes
            //    DrawPrevCubes();
                DrawTericCubes(prev_cubes);

                //当前cubes的高度下降,默认情况就应该是如此
                curr_cubes.y1 ++;

                //有按键按下
                if (command == MOVE_LEFT || command == MOVE_RIGHT || command == MOVE_DOWN || command == ROTATION)
                {
                    MoveCommand(command );
                    command = NO_ACTION;
                }

                //更新整个cubes的位置
                UpDateCurrCubesPos(&curr_cubes);
                //在game_board_cubes将当前cubes的位置置1
                SetCubes(game_board_cube, 1);
                //绘制当前cubes,并显示出来
                DrawTericCubes(curr_cubes);
            }
            //当前的cubes已经不能再下降
            else
            {
                //判断是否有一整行全都是cubes的
                //如果有则清除该行
            /*    if (command == MOVE_LEFT || command == MOVE_RIGHT || command == MOVE_DOWN || command == ROTATION)
                {
                    MoveCommand(command );
                    command = NO_ACTION;
                }
                UpDateCurrCubesPos(&curr_cubes);
                //在game_board_cubes将当前cubes的位置置1
                SetCubes(game_board_cube, 1);
                //绘制当前cubes,并显示出来
                DelayMs(20);
                DrawTericCubes(curr_cubes);
            */    

                full_row_flag = IsFullRows();
                if (full_row_flag)
                {
                    uchar full_row_count = FullRowsNum();
                    UpdateScore(full_row_count);

                    if (game_score >= 3)
                    {
                        game_score = 0;
                    //    game_level ++;
                        real_game_level ++;
                    }
                    ClearFullRows();

                    DrawScore();
                    DrawCubes(game_board_cube);
                }

                //判断游戏是否结束
                game_over_flag = 0;
                game_over_flag = IsGameOver();
                if (game_over_flag == 1)
                {
                    goto label_game_over;
                }
                //重新获得每一个柱子的最大高度
                GetHightCubePerColumn();
                //重新生成cube

                curr_cubes = next_cubes;

                next_cube_type = rand_num;
                next_cubes = InitCubes(next_cube_type);
                ShowNextCubes();
                command = NO_ACTION;
            }

            time = 0;
            start_count = 1;

            Timer_Init();        //重新打开定时器
        }
    }

    while(1);

label_stop_game:

    while (1)
    {
        KeyDown();
        if (command == CONFIRM)
        {
            command = NO_ACTION;
            Timer_Init();
            goto label_play_game;
        }
    }

label_quit_game:

    DelayMs(100);
    command = NO_ACTION;
    while(1)
    {
        KeyDown();
        if (command == CONFIRM)
        {
            command = NO_ACTION;
            goto label_play_game;
        }
        if (command == QUIT)
        {
            RestartInit();
            goto label_start_game;

        }
    }

label_game_over:

        RestartInit();
        GameMainScreen(command, game_over_flag);
        game_over_flag = 0;
        command = NO_ACTION;
        for(;;)
        {
            KeyDown();
            if (command == CONFIRM)
            {
                RestartInit();
                goto label_start_play_game;
            }
        }
        while(1);
}

//teric.c   程序的逻辑实验部分

#include "t6963.c"
#include "variable.h"

/////////////////////////////////////////////////////////////

/**************************************************************************
延时ms:延时的毫秒数
***************************************************************************/
void DelayMs(uint ms)
{
     uint iq0, iq1;
     for (iq0 = ms; iq0 > 0; iq0--)
     for (iq1 = 1000; iq1 > 0; iq1--);
}

void DrawWall()
{
    uchar y;
    uchar x;
    for (y = 0; y < GAME_BOARD_HEIGHT; y ++)
    {
        for (x = 1; x < 3; x ++)
        {
            LCM_pixel(WALL_LOC+x, y, 1);
        }
    }
}

void DrawWelcomeBoard()
{

}
void WriteCube(uchar x, uchar y, bit is_show)
{
    uchar i, j;
    if (is_show)
    {

        for (i = x; i < x + PIXEL_PER_CUBE_X; i ++)
        {
            if (i == x + PIXEL_PER_CUBE_X - 1)
            {
                LCM_pixel(i, j, 0);
                continue;
            }
            for (j = y; j < y + PIXEL_PER_CUBE_Y; j ++)
            {
                if (j == y + PIXEL_PER_CUBE_Y - 1)
                {
                    LCM_pixel(i, j, 0);
                }
                else
                {
                    LCM_pixel(i, j, 1);
                }
            }

        }
    }
    else
    {
        for (i = x; i < x + PIXEL_PER_CUBE_X; i ++)
        {
            for (j = y; j < y + PIXEL_PER_CUBE_Y; j ++)
            {
                LCM_pixel(i, j, 0);
            }
        }
    }
}

void SetGameBoardCubeBit(uint* game_board_cube, uchar x, uchar y, bit is_set)
{
    if (is_set == 1)
    {
        uint tmp = game_board_cube[y];
        game_board_cube[y] = tmp | (0x8000 >> x);
    }
    else if (is_set == 0)
    {
        uint tmp1 = game_board_cube[y];
        uint tmp2 = tmp1 & (0x8000 >> x);
        game_board_cube[y] = tmp1 & (~tmp2);
    }
}

bit IsCube(uint* game_board_cube, uchar x, uchar y)
{
    uint tmp1 = game_board_cube[y];

    bit tmp2 = tmp1 & (0x8000 >> x);
    return tmp2;
}

void DrawCube(uint* game_board_cube, uchar x, uchar y)
{
    bit flag = IsCube(game_board_cube, x, y);
    if (flag)
    {
        WriteCube(x * PIXEL_PER_CUBE_X, y * PIXEL_PER_CUBE_Y, 1);
    }
    else
    {
        WriteCube(x * PIXEL_PER_CUBE_X, y * PIXEL_PER_CUBE_Y, 0);
    }
}

void DrawCubes(uint* game_board_cube)
{
    uchar x;
    uchar y;
    for (y = 0; y < CUBE_COUNT_Y; y ++)
    {
        for (x = 0; x < CUBE_COUNT_X; x ++)
        {
            DrawCube(game_board_cube, x, y);
        }
    }
}

//bit IsLeftNoCubes(uint* game_board_cube, uchar x1, uchar y1, uchar x2, uchar y2, uchar x3, uchar y3, uchar x4, uchar y4)
bit IsLeftNoCubes(uint* game_board_cube, Cubes cube)
{
    bit flag = 0;
    bit flag1 = IsCube(game_board_cube, cube.x1-1, cube.y1);
    bit flag2 = IsCube(game_board_cube, cube.x2-1, cube.y2);
    bit flag3 = IsCube(game_board_cube, cube.x3-1, cube.y3);
    bit flag4 = IsCube(game_board_cube, cube.x4-1, cube.y4);
    if (flag1 == 0 && flag2 == 0 && flag3 == 0 && flag4 == 0)
    {
        flag = 1;
    }
    return flag;
}
//bit IsRightNoCubes(uint* game_board_cube, uchar x1, uchar y1, uchar x2, uchar y2, uchar x3, uchar y3, uchar x4, uchar y4)
bit IsRightNoCubes(uint* game_board_cube, Cubes cube)
{
    bit flag = 0;
    bit flag1 = IsCube(game_board_cube, cube.x1+1, cube.y1);
    bit flag2 = IsCube(game_board_cube, cube.x2+1, cube.y2);
    bit flag3 = IsCube(game_board_cube, cube.x3+1, cube.y3);
    bit flag4 = IsCube(game_board_cube, cube.x4+1, cube.y4);
    if (flag1 == 0 && flag2 == 0 && flag3 == 0 && flag4 == 0)
    {
        flag = 1;
    }
    return flag;
}

void UpDateCurrCubesPos(Cubes* cubes)
{
//    Cubes curr_cubes = (*cubes);
    if ((*cubes).cube_type == 0)
    {
        // - - - -

        (*cubes).x2 = (*cubes).x1+1;
        (*cubes).y2 = (*cubes).y1;
        (*cubes).x3 = (*cubes).x1+2;
        (*cubes).y3 = (*cubes).y1;
        (*cubes).x4 = (*cubes).x1+3;
        (*cubes).y4 = (*cubes).y1;
    }
    else if ((*cubes).cube_type == 1)//
    {
        // |
        // |
        // |
        // |

        (*cubes).x2 = (*cubes).x1;
        (*cubes).y2 = (*cubes).y1+1;
        (*cubes).x3 = (*cubes).x1;
        (*cubes).y3 = (*cubes).y1+2;
        (*cubes).x4 = (*cubes).x1;
        (*cubes).y4 = (*cubes).y1+3;
    }
    else if ((*cubes).cube_type == 2)
    {
        // - -
        // - -
        (*cubes).x2 = (*cubes).x1 + 1;
        (*cubes).y2 = (*cubes).y1;
        (*cubes).x3 = (*cubes).x1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 + 1;
        (*cubes).y4 = (*cubes).y1 + 1;
    }

    else if ((*cubes).cube_type == 3)
    {
        // |
        // - -
        //    |
        (*cubes).x2 = (*cubes).x1;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 + 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 + 1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }
    else if ((*cubes).cube_type == 4)
    {
        //     __
        //     |
        //__|
        (*cubes).x2 = (*cubes).x1 - 1;
        (*cubes).y2 = (*cubes).y1;
        (*cubes).x3 = (*cubes).x1 - 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 - 2;
        (*cubes).y4 = (*cubes).y1 + 1;
    }

    else if ((*cubes).cube_type == 5)
    {
        //      |
        // - -
        // |
        (*cubes).x2 = (*cubes).x1;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 - 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 - 1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }
    else if ((*cubes).cube_type == 6)
    {
        //     __
        //       |
        //    |__
        (*cubes).x2 = (*cubes).x1 + 1;
        (*cubes).y2 = (*cubes).y1 ;
        (*cubes).x3 = (*cubes).x1 + 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 + 2;
        (*cubes).y4 = (*cubes).y1 + 1;
    }
    else if ((*cubes).cube_type == 7)
    {
        //     |
        //     |
        //__|
        (*cubes).x2 = (*cubes).x1;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1;
        (*cubes).y3 = (*cubes).y1 + 2;
        (*cubes).x4 = (*cubes).x1 - 1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }

    else if ((*cubes).cube_type == 8)
    {
        //
        // |
        // |- -
        (*cubes).x2 = (*cubes).x1;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 + 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 + 2;
        (*cubes).y4 = (*cubes).y1 + 1;
    }
    else if ((*cubes).cube_type == 9)
    {
        //     |-
        //     |
        //  |
        (*cubes).x2 = (*cubes).x1 - 1;
        (*cubes).y2 = (*cubes).y1;
        (*cubes).x3 = (*cubes).x1 - 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 - 1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }

    else if ((*cubes).cube_type == 10)
    {
        //
        //- - -
        //       |
        (*cubes).x2 = (*cubes).x1 + 1;
        (*cubes).y2 = (*cubes).y1 ;
        (*cubes).x3 = (*cubes).x1 + 2;
        (*cubes).y3 = (*cubes).y1 ;
        (*cubes).x4 = (*cubes).x1 + 2;
        (*cubes).y4 = (*cubes).y1 + 1;
    }

    else if (curr_cubes.cube_type == 11)
    {
        // |
        // |
        // - -
        (*cubes).x2 = (*cubes).x1 ;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 ;
        (*cubes).y3 = (*cubes).y1 + 2;
        (*cubes).x4 = (*cubes).x1 + 1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }

    else if (curr_cubes.cube_type == 12)
    {
        // - - -
        // |
        //
        (*cubes).x2 = (*cubes).x1 + 1;
        (*cubes).y2 = (*cubes).y1;
        (*cubes).x3 = (*cubes).x1 + 2;
        (*cubes).y3 = (*cubes).y1 ;
        (*cubes).x4 = (*cubes).x1 ;
        (*cubes).y4 = (*cubes).y1 + 1;
    }

    else if ((*cubes).cube_type == 13)
    {
        // -|
        //  |
        //  |
        (*cubes).x2 = (*cubes).x1 + 1;
        (*cubes).y2 = (*cubes).y1;
        (*cubes).x3 = (*cubes).x1 + 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 + 1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }
    else if ((*cubes).cube_type == 14)
    {
        //
        //     |
        // - - -
        (*cubes).x2 = (*cubes).x1 - 2;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 - 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 ;
        (*cubes).y4 = (*cubes).y1 + 1;
    }

    else if ((*cubes).cube_type == 15)
    {
        //   |
        // - - -
        (*cubes).x2 = (*cubes).x1 - 1;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 ;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 + 1;
        (*cubes).y4 = (*cubes).y1 + 1;
    }

    else if ((*cubes).cube_type == 16)
    {
        //   |
        //   |-
        //   |
        (*cubes).x2 = (*cubes).x1 ;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 + 1;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1;
        (*cubes).y4 = (*cubes).y1 + 2;
    }

    else if ((*cubes).cube_type == 17)
    {
        //  - - -
        //    |
        //
        (*cubes).x2 = (*cubes).x1 + 1;
        (*cubes).y2 = (*cubes).y1 ;
        (*cubes).x3 = (*cubes).x1 + 2;
        (*cubes).y3 = (*cubes).y1 ;
        (*cubes).x4 = (*cubes).x1 + 1;
        (*cubes).y4 = (*cubes).y1 + 1;
    }
    else if ((*cubes).cube_type == 18)
    {
        //   |
        //  _|
        //   |
        (*cubes).x2 = (*cubes).x1 - 1;
        (*cubes).y2 = (*cubes).y1 + 1;
        (*cubes).x3 = (*cubes).x1 ;
        (*cubes).y3 = (*cubes).y1 + 1;
        (*cubes).x4 = (*cubes).x1 ;
        (*cubes).y4 = (*cubes).y1 + 2;
    }

}
Cubes InitCubes(uchar cube_type)
{
    Cubes cubes = {0};
    if (cube_type == 0)        // 。。。。
    {
        // - - - -
        cubes.x1 = CUBE_COUNT_X/2 - 2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 0;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 1)
    {

// |
// |
// |
// |

        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 0;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 2)
    {
        // - -
        // - -
        cubes.x1 = CUBE_COUNT_X/2 - 1;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 1;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 3)
    {
        // |
        // - -
        //    |
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 2;
        UpDateCurrCubesPos(&cubes);
    }

    else if (cube_type == 4)        // 。。。。
    {
        //   __
        //  |
        //__|
        cubes.x1 = CUBE_COUNT_X/2 - 2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 2;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 5)
    {
        //      |
        // - -
        // |
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 3;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 6)
    {
        //     __
        //       |
        //    |__
        cubes.x1 = CUBE_COUNT_X/2 - 1;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 3;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 7)
    {
        //     |
        //     |
        //__|
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 4;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 8)        // 。。。。
    {
        //
        // |
        // |- -
        cubes.x1 = CUBE_COUNT_X/2 - 2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 4;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 9)
    {
        //     |-
        //     |
        //  |
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
         cubes.signature = 4;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 10)
    {
        //
        //- - -
        //       |
        cubes.x1 = CUBE_COUNT_X/2 - 1;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 4;
        UpDateCurrCubesPos(&cubes);
    }

    else if (cube_type == 11)        // 。。。。
    {

        // |
        // |
        // - - 

        cubes.x1 = CUBE_COUNT_X/2 - 2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 5;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 12)
    {
        // - - -
        // |

        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 5;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 13)
    {
        // -|
        //  |
        //  |
        cubes.x1 = CUBE_COUNT_X/2 - 1;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 5;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 14)
    {
    //     |
    // - - -
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 5;
        UpDateCurrCubesPos(&cubes);
    }

    else if (cube_type == 15)
    {
        //    |
        // - - -
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 6;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 16)
    {
        //   |
        //   |-
        //   |
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 6;
        UpDateCurrCubesPos(&curr_cubes);
    }
    else if (cube_type == 17)
    {
        //  - - -
        //    | 

        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 6;
        UpDateCurrCubesPos(&cubes);
    }
    else if (cube_type == 18)
    {
        //   |
        //  _|
        //   |
        cubes.x1 = CUBE_COUNT_X/2;        //GAME_BOARD_WIDTH/2 - 1;
        cubes.y1 = 0;

        cubes.cube_type = cube_type;
        cubes.signature = 6;
        UpDateCurrCubesPos(&cubes);
    }

    return cubes;
}

void SetCubes(uint* game_board_cube, bit is_set)
{
    SetGameBoardCubeBit(game_board_cube, curr_cubes.x1, curr_cubes.y1, is_set);
    SetGameBoardCubeBit(game_board_cube, curr_cubes.x2, curr_cubes.y2, is_set);
    SetGameBoardCubeBit(game_board_cube, curr_cubes.x3, curr_cubes.y3, is_set);
    SetGameBoardCubeBit(game_board_cube, curr_cubes.x4, curr_cubes.y4, is_set);
}

void DrawTericCubes(Cubes cubes)
{
    DrawCube(game_board_cube, cubes.x1,  cubes.y1);
    DrawCube(game_board_cube, cubes.x2,  cubes.y2);
    DrawCube(game_board_cube, cubes.x3,  cubes.y3);
    DrawCube(game_board_cube, cubes.x4,  cubes.y4);
}

void GetHightCubePerColumn()
{
    uchar x, y;
//    uchar tmp1;
    bit flag;

    for (x = 0; x < CUBE_COUNT_X; x ++)
    {
        for (y = 0; y < CUBE_COUNT_Y; y++)
        {
            flag = IsCube(game_board_cube, x, y);
            if (flag == 1)
            {
                highest_cube_per_column[x] = y - 1;
                if (highest_cube_per_column[x] == 0)
                    highest_cube_per_column[x] = 0;

                break;
            }
            else if (flag == 0)
            {
                if (y == CUBE_COUNT_Y - 1)
                    highest_cube_per_column[x] = y;
            }
        }
    //    highest_cube_per_column[x]
    }
}

bit IsWall(uchar x, uchar y)
{
    bit flag = 0;
    if (x <0 || x >= CUBE_COUNT_X || y < 0 || y >= CUBE_COUNT_Y)
    {
        flag = 1;
        return flag;
    }

    return flag;
}

void RotationCubes(uchar x1, uchar y1, uchar x2, uchar y2, uchar x3, uchar y3, uchar x4, uchar y4, uchar cube_type)
{
    bit flag1, flag2, flag3, flag4;

    flag1 = IsWall(x1, y1);
    flag2 = IsWall(x2, y2);
    flag3 = IsWall(x3, y3);
    flag4 = IsWall(x4, y4);

    if (flag1 == 1 || flag2 == 1 || flag3 == 1 || flag4 == 1)
        return;

    flag1 = IsCube(game_board_cube, x1, y1);
    flag2 = IsCube(game_board_cube, x2, y2);
    flag3 = IsCube(game_board_cube, x3, y3);
    flag4 = IsCube(game_board_cube,x4, y4);

    if (flag1 == 0 && flag2 == 0 && flag3 == 0 && flag4 == 0)
    {
        curr_cubes.cube_type = cube_type;
        curr_cubes.x1 = x1;
        curr_cubes.y1 = y1;
        UpDateCurrCubesPos(&curr_cubes);
    }
}

void RotationAction(uchar signature)
{
    uchar x1, y1, x2, y2, x3, y3, x4, y4;

    if (curr_cubes.signature == 0)
    {
        if (curr_cubes.cube_type == 0)
        {

            x1 = curr_cubes.x1;
            y1 = curr_cubes.y1 - 3;

            x2 = x1;
            y2 = y1+1;
            x3 = x1;
            y3 = y1+2;
            x4 = x1;
            y4 = y1+3;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 1);

        }
        else if (curr_cubes.cube_type == 1)
        {

            x1 = curr_cubes.x4;
            y1 = curr_cubes.y4;

            x2 = x1+1;
            y2 = y1;
            x3 = x1+2;
            y3 = y1;
            x4 = x1+3;
            y4 = y1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 0);

        }
    }
    else if (signature == 1)
    {
        //do nothing
    }
    else if (signature == 2)
    {
        if (curr_cubes.cube_type == 3)
        {

            x1 = curr_cubes.x1 + 2;
            y1 = curr_cubes.y1 + 1;

            x2 = x1 - 1;
            y2 = y1;
            x3 = x1 - 1;
            y3 = y1 + 1;
            x4 = x1 - 2;
            y4 = y1 + 1;
            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 4);

        }
        else if (curr_cubes.cube_type == 4)
        {

            x1 = curr_cubes.x1 - 2;
            y1 = curr_cubes.y1 - 1;

            x2 = x1;
            y2 = y1 + 1;
            x3 = x1 + 1;
            y3 = y1 + 1;
            x4 = x1 + 1;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 3);

        }

    }
    else if (signature == 3)
    {
        if (curr_cubes.cube_type == 5)
        {
            //      |
            // - -
            // |
            x1 = curr_cubes.x3;
            y1 = curr_cubes.y3;

            x2 = x1 + 1;
            y2 = y1 ;
            x3 = x1 + 1;
            y3 = y1 + 1;
            x4 = x1 + 2;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 6);
        }
        else if (curr_cubes.cube_type == 6)
        {
            //     __
            //       |
            //    |__
            x1 = curr_cubes.x3;
            y1 = curr_cubes.y3;

            x2 = x1;
            y2 = y1 + 1;
            x3 = x1 - 1;
            y3 = y1 + 1;
            x4 = x1 - 1;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 5);
        }
    }
    else if (signature == 4)
    {
        if (curr_cubes.cube_type == 7)
        {
            //     |
            //     |
            //__|
            x1 = curr_cubes.x4;
            y1 = curr_cubes.y4 - 1;

            x2 = x1;
            y2 = y1 + 1;
            x3 = x1 + 1;
            y3 = y1 + 1;
            x4 = x1 + 2;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 8);

        }

        else if (curr_cubes.cube_type == 8)
        {
            //
            // |
            // |- -  

            x1 = curr_cubes.x1 + 1;
            y1 = curr_cubes.y1 - 1;

            x2 = x1 - 1;
            y2 = y1;
            x3 = x1 - 1;
            y3 = y1 + 1;
            x4 = x1 - 1;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 9);

        }
        else if (curr_cubes.cube_type == 9)
        {
            //     |-
            //     |
            //  |   

            x1 = curr_cubes.x3;
            y1 = curr_cubes.y3;

            x2 = x1 + 1;
            y2 = y1 ;
            x3 = x1 + 2;
            y3 = y1 ;
            x4 = x1 + 2;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 10);

        }

        else if (curr_cubes.cube_type == 10)
        {
            //
            //- - -
            //       |
            x1 = curr_cubes.x2;
            y1 = curr_cubes.y2 - 1;

            x2 = x1;
            y2 = y1 + 1;
            x3 = x1;
            y3 = y1 + 2;
            x4 = x1 - 1;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 7);

        }
    }
    else if (signature == 5)
    {
        if (curr_cubes.cube_type == 11)
        {
            // |
            // |
            // - -
            x1 = curr_cubes.x2;
            y1 = curr_cubes.y2;

            x2 = x1 + 1;
            y2 = y1;
            x3 = x1 + 2;
            y3 = y1 ;
            x4 = x1 ;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 13);
        }

        else if (curr_cubes.cube_type == 12)
        {
            // - - -
            // |
            //  

            x1 = curr_cubes.x1;
            y1 = curr_cubes.y1 - 1;

            x2 = x1 + 1;
            y2 = y1;
            x3 = x1 + 1;
            y3 = y1 + 1;
            x4 = x1 + 1;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 13);
        }

        else if (curr_cubes.cube_type == 13)
        {
            // -|
            //  |
            //  |   

            x1 = curr_cubes.x3 + 1;
            y1 = curr_cubes.y3;

            x2 = x1 - 2;
            y2 = y1 + 1;
            x3 = x1 - 1;
            y3 = y1 + 1;
            x4 = x1 ;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 14);

        }
        else if (curr_cubes.cube_type == 14)
        {
            //
            //     |
            // - - -   

            x1 = curr_cubes.x2;
            y1 = curr_cubes.y2 - 2;

            x2 = x1 - 2;
            y2 = y1 + 1;
            x3 = x1 - 1;
            y3 = y1 + 1;
            x4 = x1 ;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 11);

        }
    }
    else if (signature == 6)
    {

        if (curr_cubes.cube_type == 15)
        {
            //   |
            // - - -   

            x1 = curr_cubes.x1 - 1;
            y1 = curr_cubes.y1 - 1;

            x2 = x1 ;
            y2 = y1 + 1;
            x3 = x1 + 1;
            y3 = y1 + 1;
            x4 = x1;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 16);
        }

        else if (curr_cubes.cube_type == 16)
        {
            //   |
            //   |-
            //   |

            x1 = curr_cubes.x2;
            y1 = curr_cubes.y2;

            x2 = x1 + 1;
            y2 = y1 ;
            x3 = x1 + 2;
            y3 = y1 ;
            x4 = x1 + 1;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 17);
        }

        else if (curr_cubes.cube_type == 17)
        {
            //  - - -
            //    |
            //
            x1 = curr_cubes.x2;
            y1 = curr_cubes.y2 - 1;

            x2 = x1 - 1;
            y2 = y1 + 1;
            x3 = x1 ;
            y3 = y1 + 1;
            x4 = x1 ;
            y4 = y1 + 2;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 18);
        }
        else if (curr_cubes.cube_type == 18)
        {
            //   |
            //  _|
            //   |

            x1 = curr_cubes.x3;
            y1 = curr_cubes.y3;

            x2 = x1 - 1;
            y2 = y1 + 1;
            x3 = x1 ;
            y3 = y1 + 1;
            x4 = x1 + 1;
            y4 = y1 + 1;

            RotationCubes(x1, y1, x2, y2, x3, y3, x4, y4, 15);
        }
    }
}

void MoveCommand(uchar command)
{
    if (command == MOVE_LEFT)
    {
        if (curr_cubes.x1 > 0 && curr_cubes.x2 > 0 && curr_cubes.x3 > 0 && curr_cubes.x4 > 0)
        {

            bit flag = IsLeftNoCubes(game_board_cube, curr_cubes);
            if (flag == 1)
            {
                curr_cubes.x1 --;
            }
        }
    }
    else if (command == MOVE_RIGHT)
    {
        if (curr_cubes.x1 < CUBE_COUNT_X-1 && curr_cubes.x2 < CUBE_COUNT_X-1 &&
            curr_cubes.x3 < CUBE_COUNT_X-1 && curr_cubes.x4 < CUBE_COUNT_X-1)
        {

            bit flag = IsRightNoCubes(game_board_cube, curr_cubes);
            if (flag == 1)
            {
                curr_cubes.x1 ++;
            }
        }

    }
    else if (command == MOVE_DOWN)
    {
        uchar i;
        for (i = 0; i < 3; i ++)
        {
            if(curr_cubes.y1 < highest_cube_per_column[curr_cubes.x1]-1 &&
               curr_cubes.y2 < highest_cube_per_column[curr_cubes.x2]-1 &&
               curr_cubes.y3 < highest_cube_per_column[curr_cubes.x3]-1 &&
               curr_cubes.y4 < highest_cube_per_column[curr_cubes.x4]-1)
            {
                curr_cubes.y1 ++;
                UpDateCurrCubesPos(&curr_cubes);
            }
        }
    }
    else if (command == ROTATION)
    {

        RotationAction(curr_cubes.signature);
    }
    else if (command == NO_ACTION)
    {
        //do nothing
    }

    command = 0x04;
}

void ClearFullRow(uchar y)
{
    char yy;

    for (yy = (char)y; yy > 0; yy--)
    {
        game_board_cube[yy] = game_board_cube[yy-1];
    }

    game_board_cube[0] = 0;    

}
void ClearFullRows()
{
    uchar x, y;
    uchar tmp = 0;
    bit flag;
    for (y = 0; y < CUBE_COUNT_Y; y ++)
    {
        tmp = 0;
        for (x = 0; x < CUBE_COUNT_X; x ++)
        {
            flag = IsCube(game_board_cube, x, y);
            if (flag == 1)
            {
                tmp ++;
            }
        }

        if (tmp == CUBE_COUNT_X)
        {
            //clear that row and update the full screen
            ClearFullRow(y);
        }

    }
}

bit IsFullRow(uchar y)
{

    uchar x;
    bit flag;

    for (x = 0; x < CUBE_COUNT_X; x ++)
    {
        flag = IsCube(game_board_cube, x, y);
        if (flag == 0)
        {
            return flag;
        }

    }
    return flag;
}

bit IsFullRows()
{
    uchar y;
    bit flag;
    for (y = 0; y < CUBE_COUNT_Y; y++)
    {
        flag = IsFullRow(y);
        if (flag == 1)
            return flag;
    }
    return flag;
}

uchar FullRowsNum()
{
    uchar y = 0;
    bit flag = 0;
    uchar full_row_count = 0;
    for (y = 0; y < CUBE_COUNT_Y ; y ++)
    {
        flag = IsFullRow(y);
        if (flag == 1)
        {
            full_row_count ++;
        }
    }

    return full_row_count;
}

void UpdateScore(uchar full_row_count)
{
    if (full_row_count == 1)
    {
        game_score++;
    }
    else if (full_row_count == 2)
    {
        game_score = game_score + 4;
    }
    else if (full_row_count == 3)
    {
        game_score = game_score + 7;
    }
    else if (full_row_count == 4)
    {
        game_score = game_score + 10;
    }
    else
    {
        //do nothing
        //if the program is right ,this case won‘t be appeared
    }
}
/*
void DrawNumNone(uchar x, uchar y)
{
    LCM_pixel(x + 0, y + 0, 0);
    LCM_pixel(x + 0, y + 1, 0);
    LCM_pixel(x + 0, y + 2, 0);
    LCM_pixel(x + 0, y + 3, 0);
    LCM_pixel(x + 0, y + 4, 0);
    LCM_pixel(x + 0, y + 5, 0);

    LCM_pixel(x + 1, y + 0, 0);
    LCM_pixel(x + 1, y + 1, 0);
    LCM_pixel(x + 1, y + 2, 0);
    LCM_pixel(x + 1, y + 3, 0);
    LCM_pixel(x + 1, y + 4, 0);
    LCM_pixel(x + 1, y + 5, 0);

    LCM_pixel(x + 2, y + 0, 0);
    LCM_pixel(x + 2, y + 1, 0);
    LCM_pixel(x + 2, y + 2, 0);
    LCM_pixel(x + 2, y + 3, 0);
    LCM_pixel(x + 2, y + 4, 0);
    LCM_pixel(x + 2, y + 5, 0);

    LCM_pixel(x + 3, y + 0, 0);
    LCM_pixel(x + 3, y + 1, 0);
    LCM_pixel(x + 3, y + 2, 0);
    LCM_pixel(x + 3, y + 3, 0);
    LCM_pixel(x + 3, y + 4, 0);
    LCM_pixel(x + 3, y + 5, 0);
}
void DrawNumOne(uchar x, uchar y)
{
    LCM_pixel(x + 3, y + 0, 1);
    LCM_pixel(x + 3, y + 1, 1);
    LCM_pixel(x + 3, y + 2, 1);
    LCM_pixel(x + 3, y + 3, 1);
    LCM_pixel(x + 3, y + 4, 1);
    LCM_pixel(x + 3, y + 5, 1);
}
void DrawNumTwo(uchar x, uchar y)
{
    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 1, y, 1);
    LCM_pixel(x + 2, y, 1);
    LCM_pixel(x + 3, y, 1);
    LCM_pixel(x + 3, y + 1, 1);
    LCM_pixel(x + 3, y + 2, 1);
    LCM_pixel(x + 2, y + 2, 1);
    LCM_pixel(x + 1, y + 2, 1);
    LCM_pixel(x + 0, y + 2, 1);
    LCM_pixel(x + 0, y + 3, 1);
    LCM_pixel(x + 0, y + 4, 1);
    LCM_pixel(x + 0, y + 5, 1);
    LCM_pixel(x + 1, y + 5, 1);
    LCM_pixel(x + 2, y + 5, 1);
    LCM_pixel(x + 3, y + 5, 1);
}
void DrawNumThree(uchar x, uchar y)
{

    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 1, y, 1);
    LCM_pixel(x + 2, y, 1);
    LCM_pixel(x + 3, y, 1);
    LCM_pixel(x + 3, y + 1, 1);
    LCM_pixel(x + 3, y + 2, 1);
    LCM_pixel(x + 2, y + 2, 1);
    LCM_pixel(x + 1, y + 2, 1);
    LCM_pixel(x + 0, y + 2, 1);
    LCM_pixel(x + 3, y + 3, 1);
    LCM_pixel(x + 3, y + 4, 1);
    LCM_pixel(x + 3, y + 5, 1);
    LCM_pixel(x + 3, y + 5, 1);
    LCM_pixel(x + 2, y + 5, 1);
    LCM_pixel(x + 1, y + 5, 1);
}

void DrawNumFour(uchar x, uchar y)
{
    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 3, y, 1);
    LCM_pixel(x + 0, y + 1, 1);
    LCM_pixel(x + 3, y + 1, 1);
    LCM_pixel(x + 0, y + 2, 1);
    LCM_pixel(x + 1, y + 2, 1);
    LCM_pixel(x + 2, y + 2, 1);
    LCM_pixel(x + 3, y + 2, 1);
    LCM_pixel(x + 3, y + 3, 1);
    LCM_pixel(x + 3, y + 4, 1);
    LCM_pixel(x + 3, y + 5, 1);
}
void DrawNumFive(uchar x, uchar y)
{
    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 1, y, 1);
    LCM_pixel(x + 2, y, 1);
    LCM_pixel(x + 3, y, 1);

    LCM_pixel(x + 0, y+1, 1);

    LCM_pixel(x + 0, y+2, 1);
    LCM_pixel(x + 1, y+2, 1);
    LCM_pixel(x + 2, y+2, 1);
    LCM_pixel(x + 3, y+2, 1);

    LCM_pixel(x + 3, y+3, 1);
//    LCM_pixel1(x + 3, y+3, 1);

    LCM_pixel(x + 3, y+4, 1);
//    LCM_pixel1(x + 3, y+4, 1);

    LCM_pixel(x + 0, y+5, 1);
    LCM_pixel(x + 1, y+5, 1);
    LCM_pixel(x + 2, y+5, 1);
    LCM_pixel(x + 3, y+5, 1);
}

void DrawNumSix(uchar x, uchar y)
{
    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 1, y, 1);
    LCM_pixel(x + 2, y, 1);
    LCM_pixel(x + 3, y, 1);

    LCM_pixel(x + 0, y+1, 1);

    LCM_pixel(x + 0, y+2, 1);
    LCM_pixel(x + 1, y+2, 1);
    LCM_pixel(x + 2, y+2, 1);
    LCM_pixel(x + 3, y+2, 1);

    LCM_pixel(x + 3, y+3, 1);

    LCM_pixel(x + 3, y+4, 1);
    LCM_pixel(x + 0, y+5, 1);
    LCM_pixel(x + 1, y+5, 1);
    LCM_pixel(x + 2, y+5, 1);
    LCM_pixel(x + 3, y+5, 1);

    LCM_pixel(x + 0, y+3, 1);
    LCM_pixel(x + 0, y+4, 1);
}

void DrawNumSeven(uchar x, uchar y)
{
    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 1, y, 1);
    LCM_pixel(x + 2, y, 1);
    LCM_pixel(x + 3, y, 1);
    LCM_pixel(x + 3, y+1, 1);
    LCM_pixel(x + 3, y+2, 1);
    LCM_pixel(x + 3, y+3, 1);
    LCM_pixel(x + 3, y+4, 1);
    LCM_pixel(x + 3, y+5, 1);
}
void DrawNumEight(uchar x, uchar y)
{
    LCM_pixel(x + 0, y, 1);
    LCM_pixel(x + 1, y, 1);
    LCM_pixel(x + 2, y, 1);
    LCM_pixel(x + 3, y, 1);
    LCM_pixel(x + 3, y+1, 1);
    LCM_pixel(x + 3, y+2, 1);
    LCM_pixel(x + 3, y+3, 1);
    LCM_pixel(x + 3, y+4, 1);
    LCM_pixel(x + 3, y+5, 1);

    LCM_pixel(x + 0, y + 1, 1);
    LCM_pixel(x + 0, y + 2, 1);
    LCM_pixel(x + 1, y + 2, 1);
    LCM_pixel(x + 2, y + 2, 1);
    LCM_pixel(x + 0, y + 3, 1);
    LCM_pixel(x + 0, y + 4, 1);
    LCM_pixel(x + 0, y + 5, 1);
    LCM_pixel(x + 1, y + 5, 1);
    LCM_pixel(x + 2, y + 5, 1);
}
void DrawNumNine(uchar x, uchar y)
{
    LCM_pixel(x, y, 1);
    LCM_pixel(x+1, y, 1);
    LCM_pixel(x+2, y, 1);
    LCM_pixel(x+3, y, 1);

    LCM_pixel(x, y+1, 1);
    LCM_pixel(x+3, y+1, 1);

    LCM_pixel(x, y+2, 1);
    LCM_pixel(x+1, y+2, 1);
    LCM_pixel(x+2, y+2, 1);
    LCM_pixel(x+3, y+2, 1);

    LCM_pixel(x+3, y+3, 1);
    LCM_pixel(x+3, y+4, 1);
    LCM_pixel(x+3, y+5, 1);

}
void DrawNumZero(uchar x, uchar y)
{
    LCM_pixel(x, y, 1);
    LCM_pixel(x+1, y, 1);
    LCM_pixel(x+2, y, 1);
    LCM_pixel(x+3, y, 1);

    LCM_pixel(x, y+1, 1);
    LCM_pixel(x+3, y+1, 1);

    LCM_pixel(x, y+2, 1);
    LCM_pixel(x+3, y+2, 1);

    LCM_pixel(x, y+3, 1);
    LCM_pixel(x+3, y+3, 1);

    LCM_pixel(x, y+4, 1);
    LCM_pixel(x+3, y+4, 1);

    LCM_pixel(x, y+5, 1);
    LCM_pixel(x+1, y+5, 1);
    LCM_pixel(x+2, y+5, 1);
    LCM_pixel(x+3, y+5, 1);
}

void DrawNums(uchar x, uchar y, uchar number)
{
    DrawNumNone(x, y);
    if (number == 1)
    {
        DrawNumOne(x, y);
    }
    else if (number == 2)
    {
        DrawNumTwo(x, y);
    }
    else if (number == 3)
    {
        DrawNumThree(x, y);
    }
    else if (number == 4)
    {
        DrawNumFour(x, y);
    }
    else if (number == 5)
    {
        DrawNumFive(x, y);
    }
    else if (number == 6)
    {
        DrawNumSix(x, y);
    }
    else if (number == 7)
    {
    //    DrawNumNone(x, y);
        DrawNumSeven(x, y);
    }
    else if (number == 8)
    {
        DrawNumEight(x, y);
    }
    else if (number == 9)
    {
        DrawNumNine(x, y);
    }
    else if (number == 0)
    {

        DrawNumZero(x, y);
    }
}
*/
void DrawScore()
{
    //显示分数数字
//    game_score1 = (uchar)(game_score / 100);
//    game_score2 = (uchar)(game_score /10 % 10);
//    game_score3 = (uchar)(game_score % 10);
//    game_score4 = (uchar)(game_score % 1000);

//    DrawNums(SCORE_NUM_POS_X,                 SCORE_NUM_POS_Y, game_score1);
//    DrawNums(SCORE_NUM_POS_X +  NUM_WIDTH + 1 ,    SCORE_NUM_POS_Y, game_score2);
//    DrawNums(SCORE_NUM_POS_X + 2*(NUM_WIDTH + 1),  SCORE_NUM_POS_Y, game_score3);
//    DrawNums(SCORE_NUM_POS_X + 3*(NUM_WIDTH + 1),     SCORE_NUM_POS_Y, game_score4);

//    game_score = 129;
    LCM_print_ram(7, 0, "level");
    if (real_game_level == 1)
    {
        LCM_print_ram(7, 1, "1");
    }else if(real_game_level == 2)
    {
        LCM_print_ram(7, 1, "2");
    }else if(real_game_level == 3)
    {
        LCM_print_ram(7, 1, "3");
    }else if(real_game_level == 4)
    {
        LCM_print_ram(7, 1, "4");
    }else if(real_game_level == 5)
    {
        LCM_print_ram(7, 1, "5");
    }
    LCM_print_ram(7, 2, "Score");
    game_score_str[0] = (uchar)(game_score / 100) + 0x30;
    game_score_str[1] = (uchar)(game_score /10 % 10) + 0x30;
    game_score_str[2] = (uchar)(game_score % 10) + 0x30;

    LCM_print_ram(7, 3, game_score_str);
}

void ShowNextCubes()
{
    uchar cube_type = next_cubes.cube_type;
    uchar x1, x2, x3, x4, y1, y2, y3, y4;

    WriteCube( NEXT_CUBES_SHOW_POS_X    * PIXEL_PER_CUBE_X,     NEXT_CUBES_SHOW_POS_Y * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+1) * PIXEL_PER_CUBE_X,     NEXT_CUBES_SHOW_POS_Y * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+2) * PIXEL_PER_CUBE_X,     NEXT_CUBES_SHOW_POS_Y * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+3) * PIXEL_PER_CUBE_X,     NEXT_CUBES_SHOW_POS_Y * PIXEL_PER_CUBE_Y, 0);

    WriteCube( NEXT_CUBES_SHOW_POS_X    * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+1) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+1) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+1) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+2) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+1) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+3) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+1) * PIXEL_PER_CUBE_Y, 0);

    WriteCube( NEXT_CUBES_SHOW_POS_X    * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+2) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+1) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+2) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+2) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+2) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+3) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+2) * PIXEL_PER_CUBE_Y, 0);

    WriteCube( NEXT_CUBES_SHOW_POS_X    * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+3) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+1) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+3) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+2) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+3) * PIXEL_PER_CUBE_Y, 0);
    WriteCube((NEXT_CUBES_SHOW_POS_X+3) * PIXEL_PER_CUBE_X,     (NEXT_CUBES_SHOW_POS_Y+3) * PIXEL_PER_CUBE_Y, 0);

    if (cube_type == 4 || cube_type == 5 || cube_type == 7 )
    {
        //x4_min
        x4 = next_cubes.x4;

        x1 = NEXT_CUBES_SHOW_POS_X - x4 + next_cubes.x1;
        x2 = NEXT_CUBES_SHOW_POS_X - x4 + next_cubes.x2;
        x3 = NEXT_CUBES_SHOW_POS_X - x4 + next_cubes.x3;

        x4 = NEXT_CUBES_SHOW_POS_X; 

    }
    else if (cube_type == 9 || cube_type == 15 || cube_type == 18 || cube_type == 14)
    {
        //x2_min
        x2 = next_cubes.x2;

        x1 = NEXT_CUBES_SHOW_POS_X - x2 + next_cubes.x1;
        x3 = NEXT_CUBES_SHOW_POS_X - x2 + next_cubes.x3;
        x4 = NEXT_CUBES_SHOW_POS_X - x2 + next_cubes.x4;

        x2 = NEXT_CUBES_SHOW_POS_X;
    }
    else
    {
        //x1_min
        x1 = next_cubes.x1;

        x2 = NEXT_CUBES_SHOW_POS_X - x1 + next_cubes.x2;
        x3 = NEXT_CUBES_SHOW_POS_X - x1 + next_cubes.x3;
        x4 = NEXT_CUBES_SHOW_POS_X - x1 + next_cubes.x4;

        x1 = NEXT_CUBES_SHOW_POS_X;
    }

    y1 = next_cubes.y1;

    y2 = NEXT_CUBES_SHOW_POS_Y - y1 + next_cubes.y2;
    y3 = NEXT_CUBES_SHOW_POS_Y - y1 + next_cubes.y3;
    y4 = NEXT_CUBES_SHOW_POS_Y - y1 + next_cubes.y4;
    y1 = NEXT_CUBES_SHOW_POS_Y;

    WriteCube(x1 * PIXEL_PER_CUBE_X, y1 * PIXEL_PER_CUBE_Y, 1);
    WriteCube(x2 * PIXEL_PER_CUBE_X, y2 * PIXEL_PER_CUBE_Y, 1);
    WriteCube(x3 * PIXEL_PER_CUBE_X, y3 * PIXEL_PER_CUBE_Y, 1);
    WriteCube(x4 * PIXEL_PER_CUBE_X, y4 * PIXEL_PER_CUBE_Y, 1);

}
bit IsGameOver()
{
    uchar x;
    bit flag = 0;
    for (x = 0; x < CUBE_COUNT_X; x ++)
    {
        if (highest_cube_per_column[x] == 0)
        {
            flag = 1;
            return flag;
        }
    }
    return flag;
}

void DrawRect(uchar x1, uchar y1, uchar x2, uchar y2)
{
    uchar x, y;
    for (x = x1; x < x2; x ++)
    {
        LCM_pixel(x, y1, 1);
        LCM_pixel(x, y2, 1);
    }
    for (y = y1; y < y2; y ++)
    {
        LCM_pixel(x1, y, 1);
        LCM_pixel(x2, y, 1);
    }
}

void GameMainScreen(uchar command, bit flag)
{
    uchar x, y;
    for (x = 0; x < 5; x ++)
    {
        for (y = 0; y < 5; y ++)
        {
            DrawRect(14 + x, 12 + y, 114 - x, 52 - y);;
        }

    }

    for (x = 20; x < 110; x ++)
    {
        for (y = 17; y < 47; y ++)
        {
            LCM_pixel(x, y, 0);
        }
    }

    if (command == QUIT)
    {
        LCM_print_ram(3,3, "Really to");
        LCM_print_ram(3,4, "quit game?");
        return;
    }
    else if (command == PAUSE)
    {
        LCM_print_ram(3, 3, "Pause");
        return;
    }
    else if (flag == 1)//game is over
    {
        for (y = 0; y < CUBE_COUNT_Y; y ++)
        {
            for (x = 0; x < CUBE_COUNT_X; x ++)
            {
                SetGameBoardCubeBit(game_board_cube, x, y, 1);
                DrawCube(game_board_cube, x, y);
            }
        }
        for (x = 20; x < 110; x ++)
        {
            for (y = 17; y < 47; y ++)
            {
                LCM_pixel(x, y, 0);
            }
        }
        LCM_print_ram(3, 3,"Continue?");
    }
    else if (flag == 0)//start the game
    {
        LCM_print_ram(3,3,"Welcome to");
        LCM_print_ram(3,4,"play the");
        LCM_print_ram(3,5,"Game!");
        LCM_print_ram(3,7,"Select Level");
    }
}
void PrintMyInfo()
{
    LCM_print_ram(7,6,"08011122");
    LCM_print_ram(7,7, "czx");
}

void RestartInit()
{
    uchar y = 0;
    for (y = 0; y < CUBE_COUNT_Y; y ++)
    {
        game_board_cube[y] = 0;
    }
    command = NO_ACTION;
    LCM_clear_text();
    LCM_clear_graph1();
    LCM_clear_ram();
    PrintMyInfo();
}

//t6963.c LCD12864驱动(该部分不是本人写的)

#include <reg51.h>
#include <absacc.h>

#include "variable.h"

//端口定义
#define LCMDW        XBYTE[0x0f200]        // 数据口
#define LCMCW        XBYTE[0x0f201]        // 命令口

// T6963C 命令定义
#define LCM_CUR_POS    0x21               // 光标位置设置
#define LCM_CGR_POS    0x22               // CGRAM偏置地址设置
#define LCM_ADD_POS    0x24               // 地址指针位置
#define LCM_TXT_STP    0x40               // 文本区首址
#define LCM_TXT_WID    0x41               // 文本区宽度
#define LCM_GRH_STP    0x42               // 图形区首址
#define LCM_GRH_WID    0x43               // 图形区宽度
#define LCM_MOD_OR    0x80               // 显示方式:逻辑"或"
#define LCM_MOD_XOR    0x81               // 显示方式:逻辑"异或"
#define LCM_MOD_AND    0x83               // 显示方式:逻辑"与"
#define LCM_MOD_TCH    0x84               // 显示方式:文本特征
#define LCM_DIS_SW    0x90             // 显示开关:D0=1/0:光标闪烁启用/禁用;
                                 // D1=1/0:光标显示启用/禁用;
                                 // D2=1/0:文本显示启用/禁用;
                                 // D3=1/0:图形显示启用/禁用;
#define LCM_CUR_SHP    0xA0          //光标形状选择:0xA0-0xA7表示光标占的行数
#define LCM_AUT_WR    0xB0          // 自动写设置
#define LCM_AUT_RD    0xB1              // 自动读设置
#define LCM_AUT_OVR    0xB2              // 自动读/写结束
#define LCM_INC_WR    0xC0              // 数据一次写,地址加1
#define LCM_INC_RD    0xC1              // 数据一次读,地址加1
#define LCM_DEC_WR    0xC2              // 数据一次写,地址减1
#define LCM_DEC_RD    0xC3              // 数据一次读,地址减1
#define LCM_NOC_WR    0xC4              // 数据一次写,地址不变
#define LCM_NOC_RD    0xC5              // 数据一次读,地址不变
#define LCM_SCN_RD    0xE0              // 屏读
#define LCM_SCN_CP    0xE8              // 屏拷贝
#define LCM_BIT_OP    0xF0              // 位操作:D0-D2:定义D0-D7位;D3:1置位;0:清除 

/* ----- 定义液晶屏内部RAM  ------ */
#define LCM_T_BASE 0x00            // 文本区内存首地址
#define LCM_G_BASE 0x10            // 图形区内存首地址
#define LCM_BYTES_PER_ROW  16         // 定义屏幕文本宽度为16字节

#define LCM_G_BASE_BUFF 0x10
// 绘图坐标限制
#define LCM_XMAX 128
#define LCM_XMIN 0
#define LCM_YMAX 64
#define LCM_YMIN 0

//typedef unsigned char uchar;
//typedef unsigned int uint;
//typedef unsigned long ulong;

// 判准备好子程序
uchar fnST01(void)                  // 状态位STA1,STA0判断(读写指令和读写数据)
{
    uchar i;
    for(i=10;i>0;i--)
    {
        if((LCMCW & 0x03) == 0x03)
            break;
    }
    return i;                          // 若返回零,说明错误
}

uchar fnST2(void)                     // 状态位ST2判断(数据自动读状态)
{
    uchar i;

    for(i=10;i>0;i--)
    {
        if((LCMCW & 0x04) == 0x04)
            break;
    }
    return i;                         // 若返回零,说明错误
}

uchar fnST3(void)                         // 状态位ST3判断(数据自动写状态)
{
    uchar i;

    for(i=10;i>0;i--)
    {
        if((LCMCW & 0x08) == 0x08)
            break;
    }
    return i;                                // 若返回零,说明错误
}

uchar fnST6(void)                             // 状态位ST6判断(屏读/屏拷贝状态)
{
    uchar i;

    for(i=10;i>0;i--)
    {
        if((LCMCW & 0x40) == 0x40)
            break;
    }
    return i;                                   // 若返回零,说明错误
}

uchar fnPR10(uchar uCmd,uchar uPar1,uchar uPar2)    // 写双参数的指令
{
    if(fnST01() == 0)
        return 1;
    LCMDW = uPar1;
    if(fnST01() == 0)
        return 2;
    LCMDW = uPar2;
    if(fnST01() == 0)
        return 3;
    LCMCW = uCmd;
    return 0;                               // 返回0成功
}

uchar fnPR11(uchar uCmd,uchar uPar1)       // 写单参数的指令
{
    if(fnST01() == 0)
        return 1;
    LCMDW = uPar1;
    if(fnST01() == 0)
        return 2;
    LCMCW = uCmd;
    return 0;                                // 返回0成功
}

uchar fnPR12(uchar uCmd)                   // 写无参数的指令
{
    if(fnST01() == 0)
        return 1;
    LCMCW = uCmd;
    return 0;                                  // 返回0成功
}

uchar fnPR13(uchar uData)                      // 一次写数据
{
    if(fnST01() == 0)
        return 1;
    LCMDW = uData;
    return 0;                                   // 返回0成功
}

uchar fnPR14(uchar uData)                      // 自动写数据
{
    if(fnST3() == 0)
        return 1;
    LCMDW = uData;
    return 0;                                   // 返回0成功
}

uchar fnPR2(void)                               // 一次读数据
{
    if(fnST01() == 0)
        return 1;
    return LCMDW;
}

void LCM_set_address(uint addr)
{
    fnPR10(LCM_ADD_POS, addr & 0xFF, addr / 256);   //0x24为设定地址命令
}

//文本方式设置显示坐标
void LCM_xy(uchar x, uchar y)
{
    uint  addr;
    addr = 0x5000 + LCM_T_BASE + (y * LCM_BYTES_PER_ROW) + x;
    LCM_set_address(addr);        // 设置显示地址
}

//文本清屏
void LCM_clear_text(void)
{
    uint  i;
    fnPR10(LCM_ADD_POS, LCM_T_BASE,0x50);       // 置地址指针
    fnPR12(LCM_AUT_WR);           // 自动写
    for(i=0;i<16*8*8;i++)
    {
        fnST3();
        fnPR14(0x00);               // 写数据
    }
    fnPR12(LCM_AUT_OVR);           // 自动写结束
    fnPR10(LCM_ADD_POS, LCM_T_BASE,0x00);       // 重置地址指针}
}

// 图形清屏
void LCM_clear_graph1(void)
{
    uint  i;
    fnPR10(LCM_ADD_POS, LCM_G_BASE,0x00);       // 置地址指针

//    fnPR10(LCM_ADD_POS, LCM_G_BASE_BUFF,0x00);
    fnPR12(LCM_AUT_WR);           // 自动写
    for(i=0;i<16*8*8;i++)
    {
        fnST3();
        fnPR14(0x00);               // 写数据
    }
    fnPR12(LCM_AUT_OVR);           // 自动写结束
    fnPR10(LCM_ADD_POS, LCM_G_BASE,0x00);       // 重置地址指针
}

//清全部32KB内存
void LCM_clear_ram(void)
{
    uint  i;
    fnPR10(LCM_ADD_POS, 0x00,0x00);       // 置地址指针
    fnPR12(LCM_AUT_WR);           // 自动写
    for(i=0;i<8000;i++)
    {
        fnST3();
        fnPR14(0x00);               // 写数据
    }
    fnPR12(LCM_AUT_OVR);           // 自动写结束
    fnPR10(LCM_ADD_POS, 0x00,0x00);       // 重置地址指针
}

// 初始化显存和显示模式
uchar LCM_init (void)
{
    if(fnPR10(LCM_TXT_STP, LCM_T_BASE,0x50) != 0)    // 文本显示区首地址
        return  -1;
    fnPR10(LCM_TXT_WID, LCM_BYTES_PER_ROW,0x00);          // 文本显示区宽度
    fnPR10(LCM_GRH_STP, LCM_G_BASE,0x00);            // 图形显示区首地址
//    fnPR10(LCM_GRH_STP, LCM_G_BASE_BUFF,0x00);    

    fnPR10(LCM_GRH_WID, LCM_BYTES_PER_ROW,0x00);         // 图形显示区宽度
    fnPR12(LCM_CUR_SHP | 0x07);        // 光标形状
    fnPR10(LCM_ADD_POS, 0x00,0x00);   // 光标位置设置
    fnPR12(LCM_MOD_OR);                // 显示方式设置
    fnPR12(LCM_DIS_SW | 0x0c);            //显示设置为:图形开、文本开
     // 注意:如果设置显示光标,需要设定光标的位置
    return 0;
}

// 显示字符串RAM
void LCM_print_ram(uchar x,uchar y, uchar *string)
{
     uchar i,c;
     LCM_xy(x,y);
    fnPR12(LCM_AUT_WR);           // 自动写
     for (i=0;string[i]!=0;i++)
     {
          c = string[i] - 0x20;     // 转换ASCII码为屏幕内码
        fnPR14(c);                     // 写数据
     }
    fnPR12(LCM_AUT_OVR);           // 自动写结束
}

void LCM_pixel(uchar column, uchar row, uchar show)
{
     int addr;       // memory address of byte containing pixel to write
     if( (column>=LCM_XMAX) || (row>=LCM_YMAX) )
        return;

//    addr =  LCM_G_BASE_BUFF + (row*LCM_BYTES_PER_ROW)  + (column/8);
    addr =  LCM_G_BASE + (row*LCM_BYTES_PER_ROW)  + (column/8);
     LCM_set_address(addr);   // set LCD addr. Pointer
     if(show)
    {

        LCM_set_address(addr);
        fnPR12(0xf8+7-column%8);
    }

     else
    {
        LCM_set_address(addr);
        fnPR12(0xf0+7-column%8);
    }

}
 

基于51的俄罗斯方块

时间: 2024-10-23 18:28:38

基于51的俄罗斯方块的相关文章

基于51单片机的万年历(算法实现)

基于51单片机的万年历,用到了单片机独立键盘.数码管.LED灯模块实现. 想要简单还是DS1302好用. 1 /************************************************** 2 3 作者:纟彖氵戋 博客:http://www.cnblogs.com/yllinux/ 4 5 时间:2017年6月7日 6 7 目标:利用单片机独立键盘.数码管.LED灯模块实现万年历(算法实现) 8 9 ************************************

基于51单片机的12864驱动

/**************dis_12864.h***************/ #include <reg52.h> #ifndef __DIS_12864_H__ #define __DIS_12864_H__ #define uchar unsigned char #define uint  unsigned int /*12864端口定义*/ #define LCD_data  P0             //数据口 sbit LCD_RS  =  P1^0;          

[原创]基于51单片机的红外遥控课程设计

[注]: 一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来.希望考研失意,还能赶上“好工作”的春招班车.如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏.但请相信我!给我机会我会很认真学的! 邮箱:[email protected] 转载请注明出处呀! 基于51单片机的红外遥控课程设计 目录 第一章 设计简介... 3 第二章 系统方案... 3 一.设计方案对比... 3 二.方案设计... 4 第三章 硬件设计... 5 一.红外遥

基于51单片机的温度控制系统毕设

分享一下单片机毕设课程计参考资料33个,献给大四的朋友,毕业设计就不用愁了,如果有什么不懂的地方可以加群大家一起交流:813238832资料下载的地址:https://bbs.usoftchina.com/thread-208012-1-1.html 1.CDMA通信系统中的接入信道部分进行仿真与分析2.USB接口设计3.毕业设计(论文)OFDM通信系统基带数据4.电气工程系毕业设计开题报告5.电信运营商收入保障系统设计与实现6.基于51单片机的16×16点阵(滚动显示)7.基于51单片机的LE

基于python的俄罗斯方块小游戏

课 程 名:   python课程设计 课程设计项目名称:   基于python的俄罗斯方块 团队成员:     叶焱镔.柯博群.钱昱铭 一.项目简介 1.1 项目博客地址 1.2 项目完成的功能与特色 俄罗斯方块的游戏实现,实现了随机方块的生成.下落.旋转,游戏的进行.消除.结束,游戏的重新开始.退出.暂停,可显示最高记录.历史记录.记录的排行,可继续上回的游戏 1.3 项目采用的技术栈    python 1.4 项目借鉴源代码的地址 https://blog.csdn.net/lanseg

基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目

一.前言 1.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目包括用Keil软件编写单片机C语言程序和用Proteus软件仿真单片机外围电路 2.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目构思 (1).声明程序变量思维导图 (2).程序子函数思维导图 (3).程序主函数思维导图 二.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目的Keil软件编写的单片机C语言程序 1 #include<reg52.h>//声明51单片机

基于51单片机的无线测温系统

本51项目基于STC89C52MCU,温度传感器为DS18B20,显示模块用的是LCD1602,无线模块用的是Nodemcu. 项目用到的编程语言:C,C++,Lua. 实现思路是这样,DS18B20测温,然后数据串行传送给51单片机,然后51通过串口将数据传送给Nodemcu,Nodemcu通过其WIFI模块将数据发送给上位机,上位机上的程序是用Qt编写的GUI.(这里无线传输采用的是无连接的UDP协议) 1.DS18B20温度测量模块 DS18B20是单总线器件,所以时序要求非常严格,程序编

基于.NET的俄罗斯方块课程设计

前言 随着我国物质生活的巨大提高,人们的精神文化需求也不断提升,从温饱中解放出来的人们将会更多地关注娱乐活动.俄罗斯方块游戏就能够很好地满足人们日常简单的娱乐需求.俄罗斯方块游戏风靡于90年代,是现在青年人的美好回忆.因为俄罗斯方块游戏的规则简单,而且简单的几条规则就足够使得游戏过程变化多端,因此一直以来都被认为是益智游戏而广泛流行于人民群众中.Windows自带的游戏功能一直缺少俄罗斯方块这一个最流行最原始的游戏,因此基于C#和.NET平台开发一个俄罗斯方块游戏是很有必要的. 我们将设计实现一

基于51单片机简易操作系统设计

前言 看了很久的操作系统原理,ucos源码也看了大半,但是感觉总是懵懵懂懂,用句流行的网络用语就是始终上不了车,后来在网上被人推荐了一篇文章<建立一个属于自己的操作系统>,这篇文章真的非常好,也附有源码,但不知道是不是我找的文章有差错还是啥,我根据文章提供的源码贴代码,根本无法编译,然后开始读代码修改代码最后成功编译但是在硬件平台运行根本不行.后来又断断续续看ucos源码,反正各种什么数据结构啊的通信什么的让人头痛,后来大学的单片机原理完课,学校安排课设,我选了时钟定时器(有点像闹钟),这种开