C语言写的俄罗斯方块

/************************************
名 称:俄罗斯方块 Tetris
作 者:freewind
版 本:v2.0
时 间:2006-08
Email:freewind22@163.com
*************************************/

//头文件 tetris.h 

/************************** Const ************************************/
#define ROW 22
#define COL 10
#define WID 18
#define HEI 18
#define TRUE 1
#define FALSE 0
#define MAXSPEED 12
#define UP 1
#define DOWN 4
#define LEFT 2
#define RIGHT 3
#define QUICKDOWN 5
#define SHOW 1
#define HIDE 2
#define OPENFILE 6
#define SAVEFILE 7
#define BACKGROUND 100
#define BGCOLOR 101
#define FORECOLOR 102
#define TITLECOLOR 103
#define TITLEBGCOLOR 104
#define GAMEAREABGCOLOR 105
#define CURCOLOR 106
#define CONBTNCOLOR 107
#define CONBTNBGCOLOR 108
#define TEXTBOXCOLOR 109
#define TEXTBOXBGCOLOR 110
#define LINEHEI 16
#define MAXMODE 8
#define WIDTH 640L
/*************************** Struct *************************************/
struct Boxstatus{
    int x;
    int y;
    int have;
    int color;
};
struct Colors{
    int red;
    int green;
    int blue;
};
/************************* Declaring functions **********************/
void Init_Graph();
void Init_Color();
void Init_Data();
void Init_Map();
void Init();
int GetL(int icolor);
void GetKey(int *ah,int *al);
void Button(int x1,int y1,int x2,int y2,int icolor);
void CloseButton(int x1,int y1,int x2,int y2,int icolor);
void MinButton(int x1,int y1,int x2,int y2,int icolor);
void StatusBar(int flag,char cMsg[40]);
void OpenWindow(int x1,int y1,int x2,int y2,int btnMin,int btnClose,char cTitle[20]);
void TextBox(int l,int t,int r,int b);
void PrintScore();
void FrmMain();
void Boxs(int r,int c,int flag,int icolor);
void nBoxs(int r,int c,int flag,int icolor);
void GetBoxXY(int num,int shape,char result[10]);
void ShowBox(int iCur,int iNext);
void NewBox(int first);
void RefreshGameArea();
void SetInitLevel();
void GameStart();
void Pause(int flag);
void Arrow(int x,int y,int icolor,int idir );
void GetKeyName(int ah,int al,char result[10]);
void FrmSetKey();
void Cursor(int x,int y,int flag);
void FrmGetFileName(int OorS);
void SetColor(int iColorName);
void ShowTime();
void FrmAbout();
void CheckBox(int x,int y,int flag);
void FrmOption();
void ChangeStyle();
void ShowMenu(int refresh);
void HideMenu();
void SelectMenu();
void GameOver();
void CheckRow();
void Move(int dir);
void ChangeShape();
void Set_Mode();
void Begin();
void GetUserInfo();
void SaveUserInfo();
void MsgBox(int l,int t,int r,int b,char cMsg[81]);
void End();
void OpenFile();
void SaveFile();
void init_graph();
void pset(unsigned x,unsigned y,unsigned char color);
void gotoxy2(unsigned x,unsigned y);
void printchar(unsigned x,unsigned y,unsigned char color,unsigned char  ch);
void printstring(unsigned x,unsigned y,unsigned char color,const char * string);
void line2(int l,int t,int r,int b,unsigned char bcolor,int fill);
void Show_Title();
void Draw_AllColor();
void GetAllColors();
void drawcursor(int x,int y,int mode);
int SelectColor();

 

//主程序 tetris.c

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <time.h>
#include "tetris.h"
/*************************** Public Variable ****************************/
/*  Color   */
int iBgColor,iForeColor;
int iTitleColor,iTitleBgColor,iConBtnColor,iConBtnBgColor;
int iGameAreaBgColor,iBackGround;
int iBoxColor,iCurColor,iNextColor;
int iTextBoxBgColor,iTextBoxColor;
int iMaxColor;
int iInterface;
struct Colors Color256[256];
int iColorNum[]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};
int iCurColorMode[MAXMODE][16]={{ 17, 54,  2,  3, 41, 35, 42,  7, 8 ,  9, 10, 11, 12, 13, 14, 15},
                                { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                                { 17,120, 34,185, 33,167, 38,151,223, 53, 76,103, 44,111, 47, 31},
                                { 17,238,113, 93, 52,118, 54, 55,151,108, 10, 37, 60, 68, 70, 95},
                                { 17,126, 66,172, 42, 69, 40, 71,121,124, 74, 55, 92, 77, 60,100},
                                { 18,176,190, 83,208,162, 39, 87,230, 89, 44, 76, 92, 71, 60, 95},
                                { 17, 97,121,231,114,180, 53,103,199, 73,106, 92, 52, 47, 65, 92},
                                {247,126,114,180,110,161,118,  2,191,121, 68,123, 64, 47, 53, 50}};
int iColorValue[MAXMODE][11]={{ 0,11, 7,10, 1,11, 7,10, 2,10, 8},
                            { 0,15, 4, 1,11, 0,12, 0,13,10, 2},
                            { 0, 9, 1,12, 9,12, 9,12, 8,10,15},
                            { 0, 4,12, 4, 5, 0,14, 0,13,10, 8},
                            { 0,11, 2, 5, 0, 0,13, 0,10,10, 7},
                            { 0,10, 3,14,10, 6, 7, 6,11,10, 2},
                            { 0, 9, 6,10, 9, 9, 2,10,11,10, 7},
                            { 0,10, 7,14,13, 6, 7,12, 9,10,11}};
/*  Data   */
unsigned myname1[]={544,4088,544,544,16383,128,2032,1168,2032,1168,1168,2032,0,544,1040,2056};
unsigned myname2[]={32,4128,5116,8228,10238,28196,41980,9248,10488,9248,9212,10784,9248,10784,12799,8192};
struct Boxstatus box[ROW][COL];
struct Boxstatus nbox[4][4];
char cFileName[81];
int iFileName=FALSE;
long lScore,lGameSpeed=30000;
int iLines,iSpeed,iLevel,iInitSpeed=0,iInitLevel=0;
char cAppName[20]="Super Tetris";
int ikLeftAH=75,ikLeftAL=0,ikRightAH=77,ikRightAL=0;
int ikChangeAH=57,ikChangeAL=32,ikDownAH=80,ikDownAL=0;
int iCurRow,iCurCol,iCurNum,iCurShape,iNextNum,iNextShape;
int iCurBoxLoc[11],iNextBoxLoc[11];
char cGameStatus[10];
int iLeft=160,iTop=10,iRight=480,iBottom=458;
int iBoxStyle;
int iMaxX,iMaxY;
int iAdvMode,iRandomColor;
char cMsg1[]="F2:Start  F4:Pause  Alt+G:Menu";
char cMsg2[]="F4:Continue  Alt+G:Menu";
char cMsg3[]="Tab:Skip  Enter:Change";
int ColorMode=0;

char far *vgabase;
int curpage;

/*  Menu  */
void * vmImage;
int imiLeft=-1,imiTop;
int imMain=4,imLen=144,iExitMenu;
int iCurMenu=0,isCurMenu=0;
int imMenu[5];
char cmMain[4][10]={"Game","Edit","Color","Help"};
char *cmMenu[ ]={"Start           F2",
                         "Pause           F4",
                      "-",
                         "Open...     Ctrl+O",
                         "Save...     Ctrl+H",
                      "-",
                         "Exit",
                      "|",
                "Option...         ",
                         "Key Define  Ctrl+K",
                      "-",
                         "DateTime    Ctrl+D",
                      "-",
                         "Box Style   Ctrl+A",
                      "-",
                         "Color Mode  Ctrl+M",
                         "SelectColor Ctrl+L",
                      "|",
                "BackGround  Ctrl+B",
                          "-",
                          "FormBG      Ctrl+G",
                          "FormFore    Ctrl+F",
                          "-",
                          "TitleBG     Ctrl+V",
                          "TitleFore   Ctrl+T",
                          "-",
                          "BoxBG       Ctrl+U",
                          "BoxFore     Ctrl+I",
                          "-",
                          "ButtonBg    Ctrl+E",
                          "ButtonFore  Ctrl+R",
                          "-",
                          "TextBoxBg   Ctrl+Q",
                          "TextBoxFroe Ctrl+W",
                          "|",
                "About...        F1",
                          "|","||"};
/********************************** Init_Graph *****************************/
void Init_Graph(){
    int gdriver=DETECT,gmode,errorcode;
    /*initgraph(&gdriver, &gmode, "C://Win-TC//Tetris_C//");*/
    initgraph(&gdriver, &gmode, "");
    errorcode = graphresult();
    if (errorcode != grOk) /* an error occurred */
      {
            printf("Graphics error: %s/n", grapherrormsg(errorcode));
      printf("Press any key to halt:");
            getch();
            exit(1); /*terminate with an error code */
    }
}
/********************************* Init_Color ****************************/
void Init_Color(){
    iCurColor=3;
    iNextColor=3;  
    iBoxStyle=5;   
    ColorMode=0;
    /* 11 colors */
    iBoxColor=2;
    iBgColor=7;
    iForeColor=9;
    iTitleColor=11;
    iTitleBgColor=1;
    iConBtnColor=14;
    iConBtnBgColor=7;
    iGameAreaBgColor=8;
    iBackGround=0;
    iTextBoxBgColor=15;
    iTextBoxColor=10;  
}
/********************************* Init_Data ****************************/
void Init_Data(){
    int i,j;
    lScore=0,iLines=0;
    iSpeed=0,iLevel=0;
    iCurRow=0,iCurCol=4;
    for(i=0;i<ROW;i++)
        for (j=0;j<COL;j++){
            box[i][j].have=FALSE;
            box[i][j].color=0;
        }
    for (i=0;i<4;i++)
        for (j=0;j<4;j++){
            nbox[i][j].have=FALSE;
            nbox[i][j].color=0;
        }
}
/********************************* Init_Map ******************************/
void Init_Map(){
    int x,y,i,j;
    int l,t,r,b;
    unsigned int size;
    x=171,y=51;
    for(i=0;i<ROW;i++){
        for (j=0;j<COL;j++){
            box[i][j].x=x+j*WID;
            box[i][j].y=y+i*HEI;
        }
    }
    x+=COL*HEI+30;
    y+=35;
    for (i=0;i<4;i++)
        for (j=0;j<4;j++){
            nbox[i][j].x=x+j*WID;
            nbox[i][j].y=y+i*HEI;
        }
    /* color */
    iRandomColor=FALSE;
    iAdvMode=FALSE;
    iInterface=TRUE;
    iMaxColor=getmaxcolor();
    /* location */
    iMaxX=getmaxx();
    iMaxY=getmaxy();
    /* image */
    l=iMaxX/2-95,t=110,r=iMaxX/2+90,b=338;
    size=imagesize(l,t,r,b);
    vmImage=malloc(size);
    if(vmImage==NULL) {
        MsgBox(iMaxX/2-150,220,iMaxX/2+150,265,"Can't allocate more memory.terminating.");
        GetKey(&l,&t);
        exit(1);
    }
    /* menu */
    imMenu[0]=0,i=0,j=1;
    while(strcmp(cmMenu[i],"||")){
        if(!strcmp(cmMenu[i],"|")){
            imMenu[j]=i+1;
            j++;
        }
        i++;
    }
}
/******************************** Init **********************************/
void Init(){
    /*init_graph();*/
    int ah, al;
    GetAllColors();
    Init_Graph();
    Init_Color();
    MsgBox(200,200,440,260,"Loading...");

    Init_Data();
    Init_Map();
    GetUserInfo();
    Set_Mode();
    randomize();
}
/******************************** GetL **********************************/
 int GetL(int icolor){
    return icolor<=7?icolor+8:15;
}
/******************************** GetKey ********************************/
void GetKey(int *ah,int *al){
    union REGS r;
    r.h.ah=0;
    int86(0x16,&r,&r);
    /*return r.h.al;*/
    *ah=r.h.ah;
    *al=r.h.al;
}
/******************************** Button ********************************/
void Button(int x1,int y1,int x2,int y2,int icolor){
    int lightcolor,darkcolor;
    lightcolor=GetL(icolor);
    setfillstyle(SOLID_FILL,icolor);
    setcolor(lightcolor);
    bar3d(x1,y1,x2,y2,0,0);
    if(iInterface){
        darkcolor=icolor==8?0:8;
        setcolor(darkcolor);
        line(x2,y1,x2,y2);
        line(x1,y2,x2,y2);
    }
}
/******************************** CloseButton ****************************/
void CloseButton(int x1,int y1,int x2,int y2,int icolor){
    int i=3;
    Button(x1,y1,x2,y2,icolor);
    setcolor(iConBtnColor);
    /* / */
    line(x1+i,y1+i,x2-i,y2-i+1);
    /* / */
    line(x1+i,y2-i+1,x2-i,y1+i);
}
/********************************* MinButton ******************************/
void MinButton(int x1,int y1,int x2,int y2,int icolor){
    int i=4;
    Button(x1,y1,x2,y2,icolor);
    setcolor(iConBtnColor);
    line(x1+i,y2-i+1,x2-i,y2-i+1);
    line(x1+i,y2-i,x2-i,y2-i);
}
/*********************************** StatusBar *****************************/
void StatusBar(int flag,char cMsg[40]){
    int l,t,r,b,icolor;
    l=iLeft,t=iBottom+2,r=iRight,b=t+18;
    if (flag){
        icolor=iBgColor;
        Button(l,t,r,b,icolor);
    }else{
        icolor=iBackGround;
        setfillstyle(SOLID_FILL,icolor);
        bar(l,t,r,b);
    }  
    if (flag){
        setcolor(iForeColor);
        settextjustify(0,1);
        outtextxy(l+5,t+8,cMsg);
    }
}
/*********************************** OpenWindow ****************************/
void OpenWindow(int x1,int y1,int x2,int y2,int btnMin,int btnClose,char cTitle[20]){
    int bx=x2,i=4;
    Button(x1,y1,x2,y2,iBgColor);
    /* Title */
    setfillstyle(SOLID_FILL,iTitleBgColor);
    bar(x1+2,y1+2,x2-2,y1+16);
    /* draw icon */
    setfillstyle(SOLID_FILL,12);
    bar(x1+i,y1+i-1,x1+i*2,y1+i*2-1);
    setfillstyle(SOLID_FILL,14);
    bar(x1+i*2+2,y1+i-1,x1+i*3+2,y1+i*2-1);
    setfillstyle(SOLID_FILL,9);
    bar(x1+i,y1+i*2+1,x1+i*2,y1+i*3+1);
    setfillstyle(SOLID_FILL,10);
    bar(x1+i*2+2,y1+i*2+1,x1+i*3+2,y1+i*3+1);
    /* control button */
    if (btnClose){
        CloseButton(x2-17,y1+3,x2-5,y1+14,iConBtnBgColor);
        bx-=17;
    }
    if (btnMin){
        MinButton(bx-17,y1+3,bx-5,y1+14,iConBtnBgColor);
        bx-=17;
    }
    setcolor(iTitleColor); 
    if( iInterface){
        settextjustify(0,1);
        outtextxy(x1+20,y1+9,cTitle);
    }else{
        settextjustify(1,1);
        outtextxy(x1+(x2-x1)/2 ,y1+9,cTitle);  
    }
}
/***************************** TextBox ***********************************/
void TextBox(int l,int t,int r,int b){
    int lightcolor,darkcolor=8;
    setfillstyle(SOLID_FILL,iTextBoxBgColor);
    lightcolor=GetL(iTextBoxBgColor);
    setcolor(lightcolor);
    bar3d(l,t,r,b,0,0);
    if(iInterface){
        if(iTextBoxBgColor==8 || iTextBoxBgColor==0) darkcolor=0;
        setcolor(darkcolor);
        line(l,t,r,t);
        line(l,t,l,b);
    }
}
/***************************** PrintScore ********************************/
void PrintScore(){
    int i,x=460,y=263,lightcolor;
    char cScore[10],cLines[10],cSpeed[10],cLevel[10],cInitSpeed[10],cInitLevel[10];
    ltoa(lScore,cScore,10);
    itoa(iLines,cLines,10);
    itoa(iSpeed,cSpeed,10);
    itoa(iLevel,cLevel,10);
    if(iInitSpeed){
        itoa(iInitSpeed,cInitSpeed,10);
        strcat(cSpeed,"+");
        strcat(cSpeed,cInitSpeed);
    }
    if(iInitLevel){
        itoa(iInitLevel,cInitLevel,10);
        strcat(cLevel,"+");
        strcat(cLevel,cInitLevel);
    }
    for (i=0;i<4;i++){ 
        TextBox(x-62,y-8,x+4,y+8);
        settextjustify(2,1);
        setcolor(iTextBoxColor);
        if (i==0) outtextxy(x,y,cScore);
        if (i==1) outtextxy(x,y,cLines);
        if (i==2) outtextxy(x,y,cSpeed);
        if (i==3)   outtextxy(x,y,cLevel);
        y+=51;
    }
}
/********************************* FrmMain ********************************/
void FrmMain(){
    int imLeft,imTop;
    int isLeft,isTop,itbTop;
    char cScore[][7]={"Score:","Lines:","Speed:","Level:"};
    int i;
    imLeft=iLeft+10,imTop=iTop+27;
    isLeft=iLeft+260,isTop=iTop+235;
    itbTop=iTop+245;
    /*setfillstyle(SOLID_FILL,iBackGround);
    setcolor(iBackGround);
    bar(0,0,639,479);*/
    OpenWindow(iLeft,iTop,iRight,iBottom,1,1,cAppName);
    settextjustify(0,1);
    setcolor(iForeColor);
    /* Show Menu */
    for (i=0;i<4;i++){
        if (i) imLeft+=strlen(cmMain[i-1])*8;
        outtextxy(imLeft+i*10,imTop,cmMain[i]);
        line(imLeft+i*10,imTop+4,imLeft+i*10+6,imTop+4);
    }
    /* Game Area */
    RefreshGameArea();
    /* Score text */
    for (i=0;i<4;i++){
        setcolor(iForeColor);
        outtextxy(isLeft,isTop,cScore[i]);
        isTop+=51,itbTop+=51;
    }
    PrintScore();
}
/********************************* Boxs **********************************/
void Boxs(int r,int c,int flag,int icolor){
    int x,y,lightcolor,darkcolor;
    x=box[r][c].x;
    y=box[r][c].y;
    if (flag){
        lightcolor=GetL(icolor);
        setfillstyle(iBoxStyle,icolor);
    }else{
        icolor=iGameAreaBgColor;
        lightcolor=icolor;
        setfillstyle(SOLID_FILL,icolor);
    }
    setcolor(lightcolor);
    bar3d(x,y,x+WID-1,y+HEI-1,0,0);
    if(iInterface && flag){
        darkcolor=icolor==8?0:8;
        setcolor(darkcolor);
        line(x+WID-1,y,x+WID-1,y+HEI-1);
        line(x,y+HEI-1,x+WID-1,y+HEI-1);
    }
}
/******************************* nBoxs ***********************************/
void nBoxs(int r,int c,int flag,int icolor){
    int x,y,lightcolor,darkcolor;
    x=nbox[r][c].x;
    y=nbox[r][c].y;
    if (flag) {
        lightcolor=GetL(icolor);
        setfillstyle(iBoxStyle,icolor);
    }else{
        icolor=iBgColor;
        lightcolor=icolor;
        setfillstyle(SOLID_FILL,icolor);
    }
    setcolor(lightcolor);
    bar3d(x,y,x+WID-1,y+HEI-1,0,0);
    if(iInterface && flag){
        darkcolor=icolor==8?0:8;
        setcolor(darkcolor);
        line(x+WID-1,y,x+WID-1,y+HEI-1);
        line(x,y+HEI-1,x+WID-1,y+HEI-1);
    }
}
/***************************** GetBoxXY *******************************/
void GetBoxXY(int num,int shape,char result[10]){
    switch(num){
          case 1:
            if (shape == 1 || shape == 3) strcpy( result , "060102");
            if (shape == 2 || shape == 4) strcpy( result , "601020");
            break;
          case 2:
            strcpy(result , "606101");
            break;
          case 3:
            if (shape == 1) strcpy(result, "600601");
            if (shape == 2) strcpy(result, "600110");
            if (shape == 3) strcpy(result, "060110");
            if (shape == 4) strcpy(result, "600610");
            break;
          case 4:
            if (shape == 1 || shape == 3) strcpy(result, "666001");
            if (shape == 2 || shape == 4) strcpy(result, "610110");
            break;
          case 5:
            if (shape == 1 || shape == 3) strcpy(result, "606106");
            if (shape == 2 || shape == 4) strcpy(result, "600111");
            break;
          case 6:
            if (shape == 1) strcpy(result, "601011");
            if (shape == 2) strcpy(result, "060116");
            if (shape == 3) strcpy(result, "666010");
            if (shape == 4) strcpy(result, "610601");
            break;
          case 7:
            if (shape == 1) strcpy(result, "601016");
            if (shape == 2) strcpy(result, "660601");
            if (shape == 3) strcpy(result, "606110");
            if (shape == 4) strcpy(result, "060111");
            break;
          case 8:
            strcpy(result , "00");
            break;
          case 9:
            if (shape == 1 || shape == 3) strcpy(result,"60");
            if (shape == 2 || shape == 4) strcpy(result,"01");
            /*strcpy(result , "60");*/
            break;
          case 10:
            if (shape == 1 || shape == 3) strcpy(result,"6010");
            if (shape == 2 || shape == 4) strcpy(result,"0601");
            /*strcpy(result , "6010");*/
            break;
          case 11:
            if (shape == 1) strcpy(result, "0610");
            if (shape == 2) strcpy(result, "6006");
            if (shape == 3) strcpy(result, "6001");
            if (shape == 4) strcpy(result, "0110");
            break;
            case 12:
            strcpy(result , "60060110");
            break;
          case 13:
            if (shape == 1) strcpy(result, "66610601");
            if (shape == 2) strcpy(result, "60611011");
            if (shape == 3) strcpy(result, "06011611");
            if (shape == 4) strcpy(result, "66601610");
            break;
          case 14:
            if (shape == 1) strcpy(result, "66606110");
            if (shape == 2) strcpy(result, "61060111");
            if (shape == 3) strcpy(result, "60161011");
            if (shape == 4) strcpy(result, "66060116");
            break;
          case 15:
            if (shape == 1 || shape == 3) strcpy(result, "66060111");
            if (shape == 2 || shape == 4) strcpy(result, "60611610");
            break;
     }
}
/******************************* ShowBox *********************************/
void ShowBox(int iCur,int iNext){
    /* 1:show 2:hide */
    int i,flag;
    /* show curbox */
    if (iCur){
        if (iCur==HIDE) flag=0; else flag=1;
        for (i=1;i<=iCurBoxLoc[0];i++,i++)
            if ((iCurBoxLoc[i]> -1) && (iCurBoxLoc[i+1]> -1)){
                Boxs(iCurBoxLoc[i],iCurBoxLoc[i+1],flag,iCurColor);
         }
    }
    /* show nextbox */
    if (iNext){
        if (iNext==HIDE) flag=0; else flag=1;
        for (i=1;i<=iNextBoxLoc[0];i++,i++)
            if ((iNextBoxLoc[i]> -1) && (iNextBoxLoc[i+1]> -1)){
                nBoxs(iNextBoxLoc[i],iNextBoxLoc[i+1],flag,iNextColor);
         }
    }
}
/******************************** NewBox *********************************/
void NewBox(int first){
    int i,len;
    char result[10];
    int iMaxNum=7;
    if (iAdvMode) iMaxNum=15;
if(first>-1){ /* not open file */
    if (first){
        iCurNum=random(iMaxNum-1)+1;
        iCurShape=random(3)+1;
        if(iRandomColor) iCurColor=random(7)+1; else iCurColor=iBoxColor;
    }else{
        iCurNum=iNextNum;
        iCurShape=iNextShape;
        iCurColor=iNextColor;
    }
    iNextNum=random(iMaxNum-1)+1;
    iNextShape=random(3)+1;
    if(iRandomColor) iNextColor=random(7)+1; else iNextColor=iBoxColor;
    /* create end */
    iCurRow=0,iCurCol=4;
}
    /* CurBox */
    GetBoxXY(iCurNum,iCurShape,result);
    len=strlen(result);
    iCurBoxLoc[0]=len+2;
    for (i=1;i<=len;i++,i++){
        iCurBoxLoc[i]=result[i-1]-48;
        if (iCurBoxLoc[i]==6) iCurBoxLoc[i]=-1;
        iCurBoxLoc[i]+=iCurRow;
        iCurBoxLoc[i+1]=result[i]-48;
        if (iCurBoxLoc[i+1]==6) iCurBoxLoc[i+1]=-1;
      iCurBoxLoc[i+1]+=iCurCol;
    }
    iCurBoxLoc[i++]=iCurRow;
    iCurBoxLoc[i]=iCurCol;
    /* NextBox */
    GetBoxXY(iNextNum,iNextShape,result);
    len=strlen(result);
    iNextBoxLoc[0]=len+2;
    for (i=1;i<=len;i++){
        iNextBoxLoc[i]=result[i-1]-48;
        if (iNextBoxLoc[i]==6) iNextBoxLoc[i]=-1;
        iNextBoxLoc[i]+=1;
    }
    iNextBoxLoc[i++]=1;
    iNextBoxLoc[i]=1;
}
/******************************* RefreshGameArea ************************/
void RefreshGameArea(){
    int x=170,y=50,w,h;
    int i,j,tempcolor;
    w=x+COL*WID+1;
    h=y+ROW*HEI+1;
    /* next box */
    setfillstyle(SOLID_FILL,iBgColor);
    bar(nbox[0][0].x-1,nbox[0][0].y-1,nbox[3][3].x+WID+1,nbox[3][3].y+HEI+1);
    /* cur box */
    if (iInterface){
        tempcolor=iTextBoxBgColor;
        iTextBoxBgColor=iGameAreaBgColor;
        TextBox(x,y,w,h);
        iTextBoxBgColor=tempcolor;
    }else
        Button(x,y,w,h,iGameAreaBgColor);
    if (!strcmp(cGameStatus,"Start") || !strcmp(cGameStatus,"Pause")){
        for (i=0;i<ROW;i++)
            for (j=0;j<COL;j++)
                if (box[i][j].have) Boxs(i,j,1,box[i][j].color);
        ShowBox(SHOW,SHOW);
    }
}
/****************************** SetInitLevel *****************************/
void SetInitLevel(){
    int i,j,c,icolor;
    for (i=ROW-1;i>=ROW-iInitLevel;i--){
        j=0;
        while(j<4){
            c=random(COL-1);
            if(!box[i][c].have){
                j++;
                if(iRandomColor) icolor=random(7)+1; else icolor=iBoxColor;
                box[i][c].have=TRUE;
                box[i][c].color=icolor;
                Boxs(i,c,TRUE,icolor);
         }
        };
    }
}
/******************************* GameStart *******************************/
void GameStart(){  
    Init_Data();
    strcpy(cGameStatus,"Over");
    RefreshGameArea();
    if(iInitLevel) SetInitLevel();
    strcpy(cGameStatus,"Start");
    PrintScore();
    NewBox(1);
    ShowBox(SHOW,SHOW);
}
/********************************** Pause *******************************/
void Pause(int flag){
    StatusBar(FALSE," ");
    if(!strcmp(cGameStatus,"Start")) {
        if(flag) {
            strcpy(cGameStatus,"Pause");
            StatusBar(TRUE,cMsg2);
        }else StatusBar(TRUE,cMsg1);
    }
    else if(!strcmp(cGameStatus,"Pause")) {
        if(flag){
            strcpy(cGameStatus,"Start");
            StatusBar(FALSE,cMsg1);
        }else StatusBar(TRUE,cMsg2);
    }
}
/******************************** Arrow *********************************/
void Arrow(int x,int y,int icolor,int idir ){
    setcolor(icolor);
    switch(idir){
        case LEFT:
        case 75:
            line(x,y,x+9,y);
            line(x,y,x+3,y-2);
            line(x,y,x+3,y+2);
            break;
        case RIGHT:
        case 77:
            line(x,y,x+9,y);
            line(x+6,y-2,x+9,y);
            line(x+6,y+2,x+9,y);
            break;
        case UP:
        case 72:
            y-=4;
            line(x+5,y,x+5,y+9);
            line(x+3,y+3,x+5,y);
            line(x+7,y+3,x+5,y);
            break;
        case DOWN:
        case 80:
            y-=4;
            line(x+5,y,x+5,y+9);
            line(x+3,y+6,x+5,y+9);
            line(x+7,y+6,x+5,y+9);
            break;
    }
}
/******************************** GetKeyName ****************************/
void GetKeyName(int ah,int al,char result[10]){
    char cKeyName[13][10]={"Home","Up","PgUp"," ","Left"," ","Right"," ",
                                    "End","Down","PgDown","Insert","Delete"};
    if (al==0) strcpy(result,cKeyName[ah-71]);
    if(al>=48 && al<=57) itoa(al-48,result,10); /* 0--9 */
    if(al>=65 && al<=90) {                                    /* A--Z */
        result[0]=al;
        result[1]='/0';
    }
    if(al>=97 && al<=122){                                    /* a--z */
        result[0]=al-32;
        result[1]='/0';
    }
    if(ah==57 && al==32) strcpy(result,"Space");
    if(ah==28 && al==13) strcpy(result,"Enter");
   
}
/******************************** FrmSetKey ********************************/
void FrmSetKey(){
    int ah,al;
    int l,t,r,b,x,y;
    char cKeyName[10]="NULL";
    int iShowAll=FALSE;
    int iCurFocus=1;
    int wid=60;
    int tempLAH=ikLeftAH,tempLAL=ikLeftAL,tempRAH=ikRightAH,tempRAL=ikRightAL;
    int tempDAH=ikDownAH,tempDAL=ikDownAL,tempCAH=ikChangeAH,tempCAL=ikChangeAL;
    int iExit=FALSE;
    l=180,t=110,r=440,b=260;
    getimage(l,t,r,b,vmImage);
    OpenWindow(l,t,r,b,0,1,"Key Define");  
    StatusBar(TRUE,cMsg3);
while(!iExit){
    switch(iCurFocus){
        case 1:
            x=l+180,y=t+75+35;
            setcolor(iBgColor);
            rectangle(x-2,y-2,x+70,y+22);
            x=l+52,y=t+40;
            setcolor(iForeColor);  
            settextjustify(2,1);
            outtextxy(x,y,"Left:");
            x+=2;
            TextBox(x,y-8,x+wid,y+8);
            if((ikLeftAH==77 || ikLeftAH==75 || ikLeftAH==80 || ikLeftAH==72) && ikLeftAL==0) Arrow( x+wid-12,y,iTextBoxColor,ikLeftAH);
            else {
                GetKeyName(ikLeftAH,ikLeftAL,cKeyName);
                setcolor(iTextBoxColor);
                outtextxy(x+wid-2,y,cKeyName);
         }
            if (iCurFocus==1){
                setcolor(iForeColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            if (iShowAll) break;
        case 2:
            if (iCurFocus==2) {
                setcolor(iBgColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            x=l+52+wid+73,y=t+40;
            setcolor(iForeColor);
            settextjustify(2,1);
            outtextxy(x,y,"Right:");
            x+=2;
            TextBox(x,y-8,x+wid,y+8);
            TextBox(x,y-8,x+wid,y+8);
            if((ikRightAH==77 || ikRightAH==75 || ikRightAH==80 || ikRightAH==72) && ikRightAL==0) Arrow( x+wid-12,y,iTextBoxColor,ikRightAH);
            else {
                GetKeyName(ikRightAH,ikRightAL,cKeyName);
                setcolor(iTextBoxColor);
                outtextxy(x+wid-2,y,cKeyName);
         }
            if (iCurFocus==2){
                setcolor(iForeColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            if (iShowAll) break;
        case 3:
            if (iCurFocus==3) {
                setcolor(iBgColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            x=l+52,y=t+75;
            setcolor(iForeColor);
            settextjustify(2,1);
            outtextxy(x,y,"Down:");
            x+=2;
            TextBox(x,y-8,x+wid,y+8);
            TextBox(x,y-8,x+wid,y+8);
            if((ikDownAH==77 || ikDownAH==75 || ikDownAH==80 || ikDownAH==72) && ikDownAL==0) Arrow( x+wid-12,y,iTextBoxColor,ikDownAH);
            else {
                GetKeyName(ikDownAH,ikDownAL,cKeyName);
                setcolor(iTextBoxColor);
                outtextxy(x+wid-2,y,cKeyName);
         }
            if (iCurFocus==3){
                setcolor(iForeColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            if (iShowAll) break;
        case 4:
            if (iCurFocus==4) {
                setcolor(iBgColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            x=l+52+wid+73,y=t+75;
            setcolor(iForeColor);
            settextjustify(2,1);
            outtextxy(x,y,"Change:");
            x+=2;
            TextBox(x,y-8,x+wid,y+8);
            TextBox(x,y-8,x+wid,y+8);
            if((ikChangeAH==77 || ikChangeAH==75 || ikChangeAH==80 || ikChangeAH==72) && ikChangeAL==0) Arrow( x+wid-12,y,iTextBoxColor,ikChangeAH);
            else {
                GetKeyName(ikChangeAH,ikChangeAL,cKeyName);
                setcolor(iTextBoxColor);
                outtextxy(x+wid-2,y,cKeyName);
         }
            if (iCurFocus==4){
                setcolor(iForeColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            if (iShowAll) break;
        case 5:
            if (iCurFocus==5) {
                setcolor(iBgColor);
                rectangle(x-4,y-11,x+wid+4,y+11);
         }
            x=l+12,y=t+75+35;
            Button(x,y,x+68,y+20,iConBtnBgColor);
            setcolor(iConBtnColor);
            settextjustify(2,1);
            outtextxy(x+46,y+10,"O K");
            if (iCurFocus==5){
                setcolor(iForeColor);
                rectangle(x-2,y-2,x+70,y+22);
         }
            if (iShowAll) break;
        case 6:
            if (iCurFocus==6){
                setcolor(iBgColor);
                rectangle(x-2,y-2,x+70,y+22);
         }
            x=l+96,y=t+75+35;
            Button(x,y,x+68,y+20,iConBtnBgColor);
            setcolor(iConBtnColor);
            settextjustify(2,1);
            outtextxy(x+62,y+10,"Default");
            if (iCurFocus==6){
                setcolor(iForeColor);
                rectangle(x-2,y-2,x+70,y+22);
         }
            if (iShowAll) break;
        case 7:
            if (iCurFocus==7){
                setcolor(iBgColor);
                rectangle(x-2,y-2,x+70,y+22);
         }
            x=l+180,y=t+75+35;
            Button(x,y,x+68,y+20,iConBtnBgColor);
            setcolor(iConBtnColor);
            settextjustify(2,1);
            outtextxy(x+58,y+10,"Cancel");
            if (iCurFocus==7){
                setcolor(iForeColor);
                rectangle(x-2,y-2,x+70,y+22);
         }
            x=l+54,y=t+40;
    }
    iShowAll=TRUE; 
    GetKey(&ah,&al);
    if (ah==1 && al==27) goto Cancel;           /* Esc */
    if (ah==15 && al==9){                           /* Tab */
        if (++iCurFocus>7) iCurFocus=1;
            continue;
    }
    strcpy(cKeyName,"NULL");
    GetKeyName(ah,al,cKeyName);
    if (strcmp(cKeyName,"NULL")){
        switch(iCurFocus){
        case 1:
            ikLeftAH=ah,ikLeftAL=al;
            break;
        case 2:
            ikRightAH=ah,ikRightAL=al;
            break;
        case 3:
            ikDownAH=ah,ikDownAL=al;
            break;
        case 4:
            ikChangeAH=ah,ikChangeAL=al;
            break;
        case 5:
            if (!strcmp(cKeyName,"Enter")) iExit=TRUE;
            break;
        case 6:
            if (!strcmp(cKeyName,"Enter")){
                x=l+96,y=t+110;
                setcolor(iBgColor);
                rectangle(x-2,y-2,x+70,y+22);
                ikLeftAH=75,ikLeftAL=0;
                ikRightAH=77,ikRightAL=0;
                ikDownAH=80,ikDownAL=0;
                ikChangeAH=57,ikChangeAL=32;
                iShowAll=FALSE;
                iCurFocus=1;
         }
            break;
        case 7:
Cancel:
            ikLeftAH=tempLAH,ikLeftAL=tempLAL;
            ikRightAH=tempRAH,ikLeftAL=tempRAL;
            ikDownAH=tempDAH,ikDownAL=tempDAL;
            ikChangeAH=tempCAH,ikChangeAL=tempCAL;
            iExit=TRUE;
            break;
        }
    }
};  /* end while */
    putimage(l,t,vmImage,COPY_PUT);
    Pause(FALSE);
}
/******************************** Cursor ********************************/
void Cursor(int x,int y,int flag){
    int icolor,isave;
    isave=getcolor();
    if(flag) icolor=iTextBoxColor; else icolor=iTextBoxBgColor;
    setcolor(icolor);
    line(x,y,x,y+12);
    setcolor(isave);
}
/****************************** FrmGetFileName **************************/
void FrmGetFileName(int OorS){
    int l,t,r,b,ah,al,x,y,tx,ty,len,iResult,iCurFocus=1;
    int l2,t2,r2,b2;
    unsigned int size;
    void * vImage;
    char cTitle[10],cChar[2],cError[81];
    int iExit=FALSE,iCursor=TRUE,idelay;
    FILE *fp;  
    if(OorS==OPENFILE ) {
        strcpy(cTitle,"Open File");
        strcpy(cError,"File not exist,please input again.");
    }else{
        strcpy(cTitle,"Save File");
        strcpy(cError,"File already exist,overwrite(Y/N)");
    }
    l=iMaxX/2-120,t=150,r=iMaxX/2+120,b=270;
    getimage(l,t,r,b,vmImage);
    OpenWindow(l,t,r,b,0,1,cTitle);
    x=l+10,y=t+33;
    tx=l+12,ty=t+46;
    settextjustify(0,1);
    outtextxy(x,y,"File Name:");
    y+=10;
    TextBox(x,y,x+220,y+18);
    x=l+30,y+=42;
    Button(x,y,x+60,y+18,iConBtnBgColor);
    setcolor(iConBtnColor);
    outtextxy(x+18,y+9,"O K");
    x+=120;
    Button(x,y,x+60,y+18,iConBtnBgColor);
    setcolor(iConBtnColor);
    outtextxy(x+7,y+9,"Cancel");
    idelay=0;
    strcpy(cFileName,"");
    delay(0);
    while(!iExit){   
        while(!kbhit() && iCurFocus==1){
            delay(lGameSpeed);
            idelay++;
            if(idelay>5){
                idelay=0;
                iCursor=-iCursor+1;
                Cursor(tx,ty,iCursor);
         }
        };   
        GetKey(&ah,&al);
        if(ah==1 && al==27) {
            iExit=TRUE;
            iResult=0;
            continue;
        }
        if(ah==15 && al==9)
            if(++iCurFocus>3) iCurFocus=1;
        switch(iCurFocus){
            case 1:
                Cursor(tx,ty,TRUE);
                x=l+150,y=t+85;
                setcolor(iBgColor);
                rectangle(x-2,y-2,x+62,y+20);
                if(ah==28 && al==13) {
                    ++iCurFocus;
                    goto Enter;
             }
                cChar[0]=10;
                if(al>=48 && al<=57 || al>=65 && al<=90 ){  /* 0--9 A--Z */
                    cChar[0]=al;
                    cChar[1]='/0';
             }
                if(al>=97 && al<=122){                                 /* a--z */
                    cChar[0]=al;
                    cChar[1]='/0';
             }
                if(ah==14 && al==8){                                          /* backspace */
                    len=strlen(cFileName);
                    if(len>0){
                        Cursor(tx,ty,FALSE);
                        cFileName[len-1]='/0';
                        setfillstyle(SOLID_FILL,iTextBoxBgColor);
                        tx-=8;
                        bar(tx,ty,tx+8,ty+14);
                        Cursor(tx,ty,TRUE);
              }
             }
                if(cChar[0]!=10 && strlen(cFileName)<8){
                    strcat(cFileName,cChar);
                    Cursor(tx,ty,FALSE);
                    settextjustify(0,1);
                    setcolor(iTextBoxColor);
                    outtextxy(tx,ty+8,cChar);
                    tx+=8;
                    Cursor(tx,ty,TRUE);
             }
                break;
            case 2:
        Enter:
                Cursor(tx,ty,FALSE);
                x=l+30,y=t+85;
                if(ah==28 && al==13){
                    strcat(cFileName,".sav");
                    len=strlen(cFileName);
                    cFileName[len]='/0';
                    fp=fopen(cFileName,"r");
                    if((fp==NULL && OorS==OPENFILE) || (fp!=NULL && OorS==SAVEFILE)){
                        l2=iMaxX/2-150,t2=t+20,r2=iMaxX/2+150,b2=t+80;
                        size=imagesize(l2,t2,r2,b2);
                        vImage=malloc(size);
                        if(vImage!=NULL) getimage(l2,t2,r2,b2,vImage);
                        MsgBox(l2,t2,r2,b2,cError);
                        GetKey(&ah,&al);
                        if(OorS==SAVEFILE && (al==89 || al==121)){
                            iResult=1;
                            iExit=TRUE;
                        }else{
                            len=strlen(cFileName);
                            cFileName[len-4]='/0';
                  }
                        if(vImage!=NULL) putimage(l2,t2,vImage,COPY_PUT);
                        free(vImage); 
                        fclose(fp);
                        iCurFocus=1;
                        continue;
                    }else{
                        iResult=1;
                        iExit=TRUE;
                        fclose(fp);
              }
             }
                setcolor(iForeColor);
                rectangle(x-2,y-2,x+62,y+20);
                break;
            case 3:
                setcolor(iBgColor);
                rectangle(x-2,y-2,x+62,y+20);
                x+=120;
                if(ah==28 && al==13){
                    iExit=TRUE;
                    iResult=0;
                    break;
             }
                setcolor(iForeColor);
                rectangle(x-2,y-2,x+62,y+20);
                break;
        } 
    };
    putimage(l,t,vmImage,COPY_PUT);
    iFileName=iResult;
}
/******************************* SetColor *******************************/
void SetColor(int iColorName){
    int i,j;
    if(!strcmp(cGameStatus,"Start")) Pause(TRUE);
    switch(iColorName){
    case BACKGROUND:
        if (++iBackGround > iMaxColor) iBackGround=0;
        iColorValue[ColorMode][0]=iBackGround; 
        setfillstyle(SOLID_FILL,iBackGround);
        bar(0,0,iLeft-1,iMaxY);
        bar(iLeft,0,iRight,iTop-1);
        bar(iLeft,iBottom+1,iRight,iMaxY);
        bar(iRight+1,0,iMaxX,iMaxY);
        break;
    case BGCOLOR:
        if (++iBgColor >iMaxColor) iBgColor=0;
        iColorValue[ColorMode][2]=iBgColor;
        FrmMain();
        RefreshGameArea();
        break;
    case FORECOLOR:
        if (++iForeColor>iMaxColor) iForeColor=0;
        iColorValue[ColorMode][1]=iForeColor;  
        FrmMain();
        RefreshGameArea();
        break;
    case TITLEBGCOLOR:
        if (++iTitleBgColor>iMaxColor) iTitleBgColor=0;
        iColorValue[ColorMode][4]=iTitleBgColor;   
        FrmMain();
        RefreshGameArea();
        break;
    case TITLECOLOR:
        if (++iTitleColor>iMaxColor) iTitleColor=0;
        iColorValue[ColorMode][3]=iTitleColor; 
        FrmMain();
        RefreshGameArea();
        break;
    case GAMEAREABGCOLOR:
        if (++iGameAreaBgColor>iMaxColor) iGameAreaBgColor=0;
        iColorValue[ColorMode][10]=iGameAreaBgColor;   
        RefreshGameArea();
        break;
    case CURCOLOR:
        if(!iRandomColor){
            if (++iBoxColor>iMaxColor) iBoxColor=0;
            iCurColor=iBoxColor;
            iNextColor=iBoxColor;
            for (i=0;i<ROW;i++)
                for (j=0;j<COL;j++)
                    if(box[i][j].have) box[i][j].color=iBoxColor;
            RefreshGameArea();
        }
        break;
    case CONBTNBGCOLOR:
        if (++iConBtnBgColor>iMaxColor) iConBtnBgColor=0;
        iColorValue[ColorMode][6]=iConBtnBgColor;  
        CloseButton(iRight-17,iTop+3,iRight-5,iTop+14,iConBtnBgColor);
        MinButton(iRight-34,iTop+3,iRight-22,iTop+14,iConBtnBgColor);
        break;
    case CONBTNCOLOR:
        if (++iConBtnColor>iMaxColor) iConBtnColor=0;
        iColorValue[ColorMode][5]=iConBtnColor;
        CloseButton(iRight-17,iTop+3,iRight-5,iTop+14,iConBtnBgColor);
        MinButton(iRight-34,iTop+3,iRight-22,iTop+14,iConBtnBgColor);
        break;
    case TEXTBOXBGCOLOR:
        if (++iTextBoxBgColor>iMaxColor) iTextBoxBgColor=0;
        iColorValue[ColorMode][8]=iTextBoxBgColor; 
        PrintScore();
        break;
    case TEXTBOXCOLOR:
        if (++iTextBoxColor>iMaxColor) iTextBoxColor=0;
        iColorValue[ColorMode][7]=iTextBoxColor;   
        PrintScore();
        break;
    }
}
/******************************* ShowTime *******************************/
void ShowTime(){
    int al,ah;
    struct tm *area;
    int l=iMaxX/2-135,t=220,r=l+270,b=265;
    time_t tt;
    tt = time(NULL);
    area = localtime(&tt);
    getimage(l,t,r,b,vmImage);
    Button(l,t,r,b,iBgColor);
    settextjustify(1,1);
    setcolor(iForeColor);
    settextstyle(3,0,1);
    outtextxy(l+135,240,asctime(area));
    settextstyle(0,0,0);
    GetKey(&ah,&al);
    putimage(l,t,vmImage,COPY_PUT);
}
/****************************** showchinese *****************************/
void showchinese(int x,int y,int color,unsigned point[]){
    unsigned num,flag;
    int i,j,xx=x,yy=y;
    for(i=0;i<16;i++){
        num=point[i];
        flag=0x8000u;
        for(j=0;j<16;j++){
            if(num>=flag && flag>0) {
                putpixel(xx,yy,color); 
                num-=flag;
         }
            flag/=2u;
            xx++;
        }
        yy++,xx=x;   
    }
}
/******************************* FrmAbout *******************************/
void FrmAbout(){
    int l,r,t,b,x,y;
    int ah,al;
    l=iMaxX/2-110,r=iMaxX/2+110;
    t=100,b=245;
    getimage(l,t,r,b,vmImage);
    OpenWindow(l,t,r,b,0,1,"About");
    x=l+17,y=t+33;
    setcolor(15);
    setfillstyle(SOLID_FILL,12);
    bar3d(x,y,x+10,y+10,0,0);
    setfillstyle(SOLID_FILL,14);
    bar3d(x+12,y,x+22,y+10,0,0);
    setfillstyle(SOLID_FILL,9);
    bar3d(x,y+12,x+10,y+22,0,0);
    setfillstyle(SOLID_FILL,10);
    bar3d(x+12,y+12,x+22,y+22,0,0);
    x+=40,y+=5;
    settextjustify(0,1);
    setcolor(iForeColor);
    outtextxy(x,y,cAppName);
    y+=20;
    outtextxy(x,y,"Version:0.1 ");
    y+=20;
    outtextxy(x,y,"Author :");
    showchinese(x+60,y-10,iForeColor,myname1);
    showchinese(x+78,y-10,iForeColor,myname2);
    y+=20;
    outtextxy(x,y,"Copyright(c) 2005");
    y+=15;
    line(l+5,y,r-5,y);
    y+=15;
    outtextxy(l+15,y,"Email:Freewind22@163.com");
    GetKey(&ah,&al);
    putimage(l,t,vmImage,COPY_PUT);
    Pause(FALSE);
}
/****************************** CheckBox ********************************/
void CheckBox(int x,int y,int flag){
    int w=13,h=13;
    TextBox(x,y,x+w,y+h);
    if(flag){
        setcolor(iTextBoxColor);
        line(x+3,y+7,x+5,y+9);
        line(x+5,y+9,x+10,y+4);
    }
}
/****************************** FrmOption *******************************/
void FrmOption(){
    int l,t,r,b,x,y,i,iCurFocus=1;
    int ah,al;
    int iShowAll=FALSE,iExit=FALSE;
    int tempAdvMode=iAdvMode,tempRandomColor=iRandomColor,tempInitSpeed=iInitSpeed,tempInitLevel=iInitLevel,tempInterface=iInterface;
    long tempGameSpeed=lGameSpeed;
    char cInitSpeed[10],cInitLevel[10],cGameSpeed[10];
    char cText[6][25]={ "Game mode :  Adv",
                        "Box color :  Random",
                        "Interface :  3D",
                        "Init speed:",
                        "Init level:",
                        "Game speed:"};
    l=iMaxX/2-95,t=110,r=iMaxX/2+90,b=338;
    getimage(l,t,r,b,vmImage);
    OpenWindow(l,t,r,b,0,1,"Option");
    x=l+15,y=t+40;
    settextjustify(0,1);
    setcolor(iForeColor);
    for (i=0;i<6;i++){
        outtextxy(x,y,cText[i]);
        y+=25;
    }
    y+=5;
    Button(x,y,x+62,y+16,iConBtnBgColor);
    setcolor(iConBtnColor);
    outtextxy(x+19,y+8,"O K");
    x=l+103;
    Button(x,y,x+62,y+16,iConBtnBgColor);
    setcolor(iConBtnColor);
    outtextxy(x+7,y+8,"Cancel");
    x=l+103,t+=2;
    StatusBar(TRUE,cMsg3);
    while (!iExit){
        switch(iCurFocus){
            case 1:
                y=t+194;
                setcolor(iBgColor);
                rectangle(x-2,y-3,x+64,y+17);
                y=t+30;
                setcolor(iForeColor);
                rectangle(x-2,y-3,x+64,y+17);
                CheckBox(x,y,iAdvMode);      
                if (iShowAll) break;
            case 2:
                if(iCurFocus==2){
                    y=t+30;
                    setcolor(iBgColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                y=t+55;
                CheckBox(x,y,iRandomColor);
                if(iCurFocus==2){
                    setcolor(iForeColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                if (iShowAll) break;
            case 3:
                if(iCurFocus==3){
                    setcolor(iBgColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                y=t+80;
                CheckBox(x,y,iInterface);
                if(iCurFocus==3){
                    setcolor(iForeColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                if (iShowAll) break;
            case 4:
                if(iCurFocus==4){
                    setcolor(iBgColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                y=t+105;
                TextBox(x,y-1,x+62,y+15);
                settextjustify(2,1);
                setcolor(iTextBoxColor);
                itoa(iInitSpeed,cInitSpeed,10);
                outtextxy(x+59,y+8,cInitSpeed);
                if(iCurFocus==4){
                    setcolor(iForeColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                if (iShowAll) break;
            case 5:
                if(iCurFocus==5){
                    setcolor(iBgColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                y=t+130;
                TextBox(x,y-1,x+62,y+15);
                settextjustify(2,1);
                setcolor(iTextBoxColor);
                itoa(iInitLevel,cInitLevel,10);
                outtextxy(x+59,y+8,cInitLevel);
                if(iCurFocus==5){
                    setcolor(iForeColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                if (iShowAll) break;
            case 6:
                if(iCurFocus==6){
                    setcolor(iBgColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                y=t+155;
                TextBox(x,y-1,x+62,y+15);
                settextjustify(2,1);
                setcolor(iTextBoxColor);
                ltoa(lGameSpeed/1000L,cGameSpeed,10);
                outtextxy(x+59,y+8,cGameSpeed);
                if(iCurFocus==6){
                    setcolor(iForeColor);
                    rectangle(x-2,y-3,x+64,y+17);
             }
                break;
            case 7:
                setcolor(iBgColor);
                rectangle(x-2,y-3,x+64,y+17);
                setcolor(iForeColor);
                y=t+194;
                rectangle(l+13,y-3,l+15+64,y+17);
                break;         
            case 8:
                setcolor(iBgColor);
                rectangle(l+13,y-3,l+15+64,y+17);
                setcolor(iForeColor);
                rectangle(x-2,y-3,x+64,y+17);
        }
        iShowAll=TRUE;
        GetKey(&ah,&al);
        if(ah==1 && al==27) iExit=TRUE;     /* ESC */
        if(ah==15 && al==9)                             /* Tab */
            if(++iCurFocus>8) iCurFocus=1;
        if(ah==28 && al==13){                           /* Enter */
            switch(iCurFocus){
                case 1:
                    if(iAdvMode) iAdvMode=FALSE; else iAdvMode=TRUE;
                    break;
                case 2:
                    if(iRandomColor) iRandomColor=FALSE; else iRandomColor=TRUE;
                    break;
                case 3:
                    if(iInterface) iInterface=FALSE; else iInterface=TRUE;
                    break;
                case 4:
                    if(++iInitSpeed>MAXSPEED) iInitSpeed=0;
                    break;
                case 5:
                    if(++iInitLevel>MAXSPEED) iInitLevel=0;
                    break;
                case 6:
                    lGameSpeed+=1000L;
                    if(lGameSpeed>45000) lGameSpeed=1000L;
                    break;
                case 7:
                    iExit=TRUE;
                    break;
                case 8:
                    iAdvMode=tempAdvMode,iRandomColor=tempRandomColor;
                    iInitSpeed=tempInitSpeed,iInitLevel=tempInitLevel;
                    iInterface=tempInterface;
                    lGameSpeed=tempGameSpeed;
                    iExit=TRUE;
         }
        }
    }; 
    putimage(l,t-2,vmImage,COPY_PUT);  
    if (!tempInterface==iInterface){
        FrmMain();
        RefreshGameArea();
    }
    Pause(FALSE);
}
/****************************** ChangeStyle *****************************/
void ChangeStyle(){
    if (!strcmp(cGameStatus,"Start") || !strcmp(cGameStatus,"Pause")){
        if (!strcmp(cGameStatus,"Start")) Pause(TRUE);
        if (++iBoxStyle>11) iBoxStyle=1;
        RefreshGameArea();
    }
}
/******************************* ShowMenu *******************************/
void ShowMenu(int refresh){
    int x[5],y=46,i,j,lightcolor,darkcolor;
    int l,t,r,b;
    x[0]=166;
    for (i=1;i<5;i++)
        x[i]=x[i-1]+strlen(cmMain[i-1])*8+10;
    settextjustify(0,1);
    lightcolor=GetL(iBgColor);
    darkcolor=iBgColor==8?0:8;
    if (refresh && imiLeft>-1){
        putimage(imiLeft,imiTop,vmImage,COPY_PUT);
    }
    if (refresh && iCurMenu>-1){
        i=iCurMenu;
        l=x[i],t=y,r=x[i]+imLen+14,b=y+(imMenu[i+1]-imMenu[i]-1) * LINEHEI + 2;
        imiLeft=l,imiTop=t;      
        getimage(l,t,r,b,vmImage);
        Button(l,t,r,b,iBgColor);
        setcolor(lightcolor);
        rectangle(x[i],t-16,x[i+1]-5,t-2);
        if(iInterface){
            setcolor(darkcolor);
            line(x[i],t-16,x[i+1]-5,t-16);
            line(x[i],t-16,x[i],t-2);
        }
        for (j=0;j<imMenu[i+1]-imMenu[i]-1;j++){
            if(!strcmp(cmMenu[imMenu[i]+j],"-")){
                setcolor(10);
                line(x[i]+7,y+10+j*LINEHEI,x[i]+imLen+7,y+10+j * LINEHEI);
            }else{
                setcolor(iForeColor);
                outtextxy(x[i]+7,y+10+j * LINEHEI,cmMenu[imMenu[i]+j]);
         }
        }/* end for */
    }/* end if */
    /* show curmenu */
    if(iCurMenu>-1){
        i=isCurMenu,j=iCurMenu;
        setfillstyle(SOLID_FILL,iTitleBgColor);
        setcolor(iTitleColor); 
        bar(x[j]+2,y+2+i*LINEHEI,x[j]+imLen+12,y+(i+1)*LINEHEI);
        outtextxy(x[j]+7,y+10+i*LINEHEI,cmMenu[imMenu[j]+i]);
    }
}
/******************************* HideMenu ********************************/
void HideMenu(){
    int x[5],y=46,i;
    x[0]=166;
    for (i=1;i<5;i++)
        x[i]=x[i-1]+strlen(cmMain[i-1])*8+10;
    setcolor(iBgColor);
    rectangle(x[iCurMenu],y-16,x[iCurMenu+1]-5,y-2);
    iCurMenu=-1;
    isCurMenu=-1;
    ShowMenu(TRUE);
    imiLeft=-1;
    iExitMenu=TRUE;
    if(!strcmp(cGameStatus,"Start")) Pause(TRUE);
}
/******************************* SelectMenu ******************************/
void SelectMenu(){
    int ah,al;
    int x[5],y=46,i,j;
    x[0]=166;
    iExitMenu=FALSE;
    for (i=1;i<4;i++)
        x[i]=x[i-1]+strlen(cmMain[i-1])*8+10;
    x[4]=x[3]+42;
    ShowMenu(TRUE);
    StatusBar(FALSE," ");
    while (!iExitMenu){
        GetKey(&ah,&al);
        if (ah==1 && al==27){           /* ESC */
            HideMenu();
            continue;
        }
        if (ah==75 && al==0){  /* <-  */
            setcolor(iBgColor);
            rectangle(x[iCurMenu],y-16,x[iCurMenu+1]-5,y-2);
            if (--iCurMenu<0) iCurMenu=3;
            isCurMenu=0;
            ShowMenu(TRUE);
            continue;
        }
        if (ah==77 && al==0){  /* -> */
            setcolor(iBgColor);
            rectangle(x[iCurMenu],y-16,x[iCurMenu+1]-5,y-2);
            if (++iCurMenu>3) iCurMenu=0;
            isCurMenu=0;
            ShowMenu(TRUE);
            continue;
        }
        /* hide menu */
        if((ah==72 && al==0) || (ah==80 && al==0)){
            i=isCurMenu,j=iCurMenu;
            setfillstyle(SOLID_FILL,iBgColor);
            setcolor(iForeColor);
            bar(x[j]+2,y+2+i*LINEHEI,x[j]+imLen+12,y+(i+1)*LINEHEI);
            outtextxy(x[j]+7,y+10+i*LINEHEI,cmMenu[imMenu[j]+i]);
        }
        /*           */
        if (ah==72 && al==0){  /* Up  */
            isCurMenu--;      
            if (isCurMenu<0) isCurMenu=imMenu[iCurMenu+1]-imMenu[iCurMenu]-2;
            if (!strcmp(cmMenu[imMenu[iCurMenu]+isCurMenu],"-")) isCurMenu--;
            ShowMenu(FALSE);
        }
        if (ah==80 && al==0){  /* Down */
            isCurMenu++;
            if (isCurMenu>imMenu[iCurMenu+1]-imMenu[iCurMenu]-2) isCurMenu=0;
            if (!strcmp(cmMenu[imMenu[iCurMenu]+isCurMenu],"-")) isCurMenu++;
            ShowMenu(FALSE);
        }
        if (ah==28 && al==13){  /* Enter */
            i=isCurMenu;
            j=iCurMenu;
            HideMenu();
            switch(j){
                case 0: /* Game */
                    switch(i){
                        case 0: /* Start */
                            GameStart();
                            break;
                        case 1: /* Pause */
                            Pause(TRUE);
                            break;
                        case 3: /* Open */
                            OpenFile();
                            break;
                        case 4: /* Save */
                            if(!strcmp(cGameStatus,"Start")) SaveFile();
                            break;
                        case 6: /* Exit */
                            End();
              }
                    break;
                case 1: /* Edit */
                    switch(i){
                        case 0: /* Option... */
                            FrmOption();
                            break;
                        case 1: /* Key set */
                            FrmSetKey();
                            break;
                        case 3: /* ShowTime */
                            ShowTime();
                            break;
                        case 5: /* Change Box Style */
                            ChangeStyle();
                            break;
                        case 7: /* Change Color Mode */
                            ColorMode++;
                            if(ColorMode>=MAXMODE) ColorMode=0;
                            Set_Mode();
                            FrmMain();
                            RefreshGameArea();
                            break;
                        case 8: /* Select Color */
                            SelectColor();
                            Init_Graph();
                            Set_Mode();
                            FrmMain();
                            RefreshGameArea();
                            break;
              }
                    break;
                case 2: /* Color */
                    switch(i){
                        case 0:
                            SetColor(BACKGROUND);
                            break;
                        case 2:
                            SetColor(BGCOLOR);
                            break;
                        case 3:
                            SetColor(FORECOLOR);
                            break;
                        case 5:
                            SetColor(TITLEBGCOLOR);    
                            break;
                        case 6:
                            SetColor(TITLECOLOR);
                            break;
                        case 8:
                            SetColor(GAMEAREABGCOLOR);
                            break;
                        case 9:
                            SetColor(CURCOLOR);
                            break;
                        case 11:
                            SetColor(CONBTNBGCOLOR);
                            break;
                        case 12:
                            SetColor(CONBTNCOLOR);
                            break;
                        case 14:
                            SetColor(TEXTBOXBGCOLOR);
                            break;
                        case 15:
                            SetColor(TEXTBOXCOLOR);
                            break;
              }
                    break;
                case 3: /* Help */
                    FrmAbout();
                    break;      
            }/* end switch */
        } /* end if */
    };/* end while */
}
/******************************** GameOver *******************************/
void GameOver(){
    int ah,al,l,t,r,b;
    l=box[1][1].x,t=220,r=box[1][9].x,b=265;
    getimage(l,t,r,b,vmImage);
    strcpy(cGameStatus,"Over");
    Button(l,t,r,b,iBgColor);
    settextjustify(1,1);
    setcolor(iForeColor);
    settextstyle(1,0,3);
    outtextxy(box[1][5].x,240,"Game Over");
    settextstyle(0,0,0);
    GetKey(&ah,&al);
    putimage(l,t,vmImage,COPY_PUT);
}
/******************************** CheckRow *******************************/
void CheckRow(){
    int i,j,r,totalrow=0,fullrow;
    for (i=ROW-1;i>=0;i--){
        fullrow=1;
        for (j=0;j<COL;j++)
                if (!box[i][j].have) fullrow=0;
        if (fullrow){
            totalrow++;
            for (r=i;r>=1;r--){
                for (j=0;j<COL;j++){
                    box[r][j].have=box[r-1][j].have;
                    box[r][j].color=box[r-1][j].color;
                    Boxs(r,j,box[r][j].have,box[r][j].color);
             }
            }/* end for */
            i++; 
        }/* end if */
    }
    switch(totalrow){
        case 1:
            lScore+=100L;
            break;
        case 2:
            lScore+=300L;
            break;
        case 3:
            lScore+=700L;
            break;
        case 4:
            lScore+=1500L;
    }
    if (totalrow) {
        iSpeed=lScore/10000;
        iLevel=iSpeed;
        iLines+=totalrow;
        PrintScore();
    }
}
/******************************** Move ***********************************/
void Move(int dir){
    int i,n,canmove=1;
    n=iCurBoxLoc[0];
    switch(dir){
        case RIGHT:                 /* Right */
            for (i=2;i<=n;i++,i++)
                if (box[iCurBoxLoc[i-1]][iCurBoxLoc[i]+1].have || iCurBoxLoc[i]+1>=COL) canmove=0;
            if (canmove){
                ShowBox(HIDE,FALSE);
                iCurCol++;
                for (i=2;i<=n;i++,i++)
                    iCurBoxLoc[i]++;
                ShowBox(SHOW,FALSE);
         }
            break;
        case LEFT:                  /* Left */
            for (i=2;i<=n;i++,i++)
                if (box[iCurBoxLoc[i-1]][iCurBoxLoc[i]-1].have || iCurBoxLoc[i]-1<0) canmove=0;
            if (canmove){
                ShowBox(HIDE,FALSE);
                iCurCol--;
                for (i=2;i<=n;i++,i++)
                    iCurBoxLoc[i]--;
                ShowBox(SHOW,FALSE);
         }
            break;
        case QUICKDOWN:             /* QuickDown */
            ShowBox(HIDE,FALSE);
            while(canmove){
                for (i=1;i<=n;i++,i++){
                    if (box[iCurBoxLoc[i]+1][iCurBoxLoc[i+1]].have || iCurBoxLoc[i]+1>=ROW){
                        canmove=0;
                        break;
              }
                    iCurBoxLoc[i]++;
             }
            };
            while(i-1){
                i-=2;
                iCurBoxLoc[i]--;
            };
            ShowBox(SHOW,FALSE); /* no break; */
        case DOWN:              /* Down */
        if (canmove){
            for (i=1;i<=n;i++,i++)
                if (box[iCurBoxLoc[i]+1][iCurBoxLoc[i+1]].have || iCurBoxLoc[i]+1>=ROW) canmove=0;
        }
            if (canmove){
                ShowBox(HIDE,FALSE);
                iCurRow++;
                for (i=1;i<=n;i++,i++)
                    iCurBoxLoc[i]++;
                ShowBox(SHOW,FALSE);
            }else{
                for (i=1;i<=n;i++,i++){
                    if(iCurBoxLoc[i]<0) goto lGameOver;
                    box[iCurBoxLoc[i]][iCurBoxLoc[i+1]].have=TRUE;
                    box[iCurBoxLoc[i]][iCurBoxLoc[i+1]].color=iCurColor;
             }
                CheckRow();
                ShowBox(FALSE,HIDE);
                NewBox(0);
                ShowBox(SHOW,SHOW);
         }
            break;
    lGameOver:
        GameOver();
    }  
}
/******************************* ChangeShape *****************************/
void ChangeShape(){
    int t[11],i,len,canchange=1;
    char result[10];
    if(iCurShape==4) iCurShape=1; else iCurShape++;
    GetBoxXY(iCurNum,iCurShape,result);
    len=strlen(result);
    for (i=1;i<=len;i++,i++){
        t[i]=result[i-1]-48;
        if (t[i]==6) t[i]=-1;
        t[i]+=iCurRow;
        t[i+1]=result[i]-48;
        if (t[i+1]==6) t[i+1]=-1;
        t[i+1]+=iCurCol;
        if (t[i]>-1)
            if ( t[i]>=ROW || t[i+1]<0 || t[i+1]>=COL || box[t[i]][t[i+1]].have) canchange=0;
    }
    if (canchange){
        ShowBox(HIDE,FALSE);
        for (i=1;i<=len;i++)
            iCurBoxLoc[i]=t[i];
        ShowBox(SHOW,FALSE);     
    }else
        if(iCurShape==1) iCurShape=4; else iCurShape--;
}
/************************** Set_Mode() *********************************/
void Set_Mode(){
    int i;
    for(i=0;i<16;i++){
        outportb(0x3c8,iColorNum[i]);
        outportb(0x3c9,Color256[iCurColorMode[ColorMode][i]].red); 
        outportb(0x3c9,Color256[iCurColorMode[ColorMode][i]].green);
        outportb(0x3c9,Color256[iCurColorMode[ColorMode][i]].blue);
    }
    iBackGround=iColorValue[ColorMode][0];       
    iForeColor=iColorValue[ColorMode][1];     
    iBgColor=iColorValue[ColorMode][2];      
    iTitleColor=iColorValue[ColorMode][3];   
    iTitleBgColor=iColorValue[ColorMode][4];      
    iConBtnColor=iColorValue[ColorMode][5];       
    iConBtnBgColor=iColorValue[ColorMode][6];     
    iTextBoxColor=iColorValue[ColorMode][7];          
    iTextBoxBgColor=iColorValue[ColorMode][8];       
    iBoxColor=iColorValue[ColorMode][9];
    iGameAreaBgColor=iColorValue[ColorMode][10];
}
/******************************** Begin **********************************/
void Begin(){
    int al,ah;
    int iDelay=0;
    while (TRUE){
        while (!kbhit() && !strcmp(cGameStatus,"Start")){
            delay(lGameSpeed);
            iDelay++;
            if(iDelay >= (MAXSPEED-iSpeed-iInitSpeed)){
                iDelay=0;
                Move(DOWN);
         }
        };
        GetKey(&ah,&al);
        /*if (ah==1 && al==27) break;       / * ESC    */
        if (ah==59 && al==0) FrmAbout();
        if (ah==60 && al==0) {              /* F2     */
            GameStart();
        }
        if (ah==62 && al==0) {              /* F4     */
            Pause(TRUE);
        }
        if (ah==24 && al==15){              /* Ctrl+O */
            OpenFile();
        }
        if (ah==50 && al==13){              /* Ctrl+M */
            ColorMode++;
            if(ColorMode>=MAXMODE) ColorMode=0;
            Set_Mode();
            FrmMain();
            RefreshGameArea();
        }
        if (ah==38 && al==12){              /* Ctrl+L */
            SelectColor();
            Init_Graph();
            Set_Mode();
            FrmMain();
            RefreshGameArea();
        }
        if (ah==35 && al==8) {              /* Ctrl+H */
            if(!strcmp(cGameStatus,"Start")) SaveFile();
        }
        if (ah==48 && al==2) {              /* Ctrl+B */
            SetColor(BACKGROUND);
        }
        if (ah==34 && al==7) {              /* Ctrl+G */
            SetColor(BGCOLOR);
        }
        if (ah==33 && al==6) {              /* Ctrl+F */
            SetColor(FORECOLOR);
        }
        if (ah==47 && al==22){              /* Ctrl+V */
            SetColor(TITLEBGCOLOR);
        }
        if (ah==20 && al==20){              /* Ctrl+T */
            SetColor(TITLECOLOR);
        }
        if (ah==22 && al==21){              /* Ctrl+U */
            SetColor(GAMEAREABGCOLOR);
        }
        if (ah==23 && al==9) {              /* Ctrl+I */
            SetColor(CURCOLOR);
        }
        if (ah==18 && al==5) {              /* Ctrl+E */
            SetColor(CONBTNBGCOLOR);
        }
        if (ah==19 && al==18){              /* Ctrl+R */
            SetColor(CONBTNCOLOR);
        }
        if (ah==16 && al==17){              /* Ctrl+Q */
            SetColor(TEXTBOXBGCOLOR);
        }
        if (ah==17 && al==23){              /* Ctrl+W */
            SetColor(TEXTBOXCOLOR);
        }
        if (ah==37 && al==11){              /* Ctrl+K */
            FrmSetKey();
        }
        if (ah==32 && al==4) {              /* Ctrl+D */
            ShowTime();
        }
        if (ah==30 && al==1) {              /* Ctrl+A */
            ChangeStyle();
        }
        if (ah==ikLeftAH && al==ikLeftAL){  /* <-  */
            if (!strcmp(cGameStatus,"Start")) Move(LEFT);
        }
        if (ah==ikRightAH && al==ikRightAL){ /* -> */
            if (!strcmp(cGameStatus,"Start")) Move(RIGHT);
        }
        if (ah==ikChangeAH && al==ikChangeAL){
            if (!strcmp(cGameStatus,"Start")) ChangeShape();
        }
        if (ah==ikDownAH && al==ikDownAL) {  /* Down */
            if (!strcmp(cGameStatus,"Start")) Move(QUICKDOWN);
        }
        if (ah==34 && al==0) {          /* Alt+G */
            iCurMenu=0;
            isCurMenu=0;
            imiLeft=-1;
            SelectMenu();
        }
        if (ah==18 && al==0) {          /* Alt+E */
            iCurMenu=1;
            isCurMenu=0;
            imiLeft=-1;
            SelectMenu();
        }
        if (ah==46 && al==0) {          /* Alt+C */
            iCurMenu=2;
            isCurMenu=0;
            imiLeft=-1;
            SelectMenu();
        }
        if (ah==35 && al==0) {          /* Alt+H */
            iCurMenu=3;
            isCurMenu=0;
            imiLeft=-1;
            SelectMenu();
        }
    };
}
/******************************* GetUserInfo ****************************/
void GetUserInfo(){
    FILE * fp;
    char cLine[81];
    char cRight[4];
    int i,iValue,len,j;
    i=0;
    fp=fopen("tetris.ini","r");
    cRight[3]='/0';
    if(!fp==NULL){
        while(fgets(cLine,80,fp)){
            len=strlen(cLine);
            cRight[0]=cLine[len-3];
            cRight[1]=cLine[len-2];
            cRight[2]='/0';
            iValue=atoi(cRight);
            i++;
            if(i==1) if(iValue==0 || iValue==1) iAdvMode=iValue;
            if(i==2) if(iValue==0 || iValue==1) iRandomColor=iValue;
            if(i==3) if(iValue>=0 && iValue<=MAXSPEED) iInitSpeed=iValue;
            if(i==4) if(iValue>=0 && iValue<=MAXSPEED) iInitLevel=iValue;
            if(i==5) if(iValue>0 && iValue<=11) iBoxStyle=iValue;
            if(i==6) if(iValue==0 || iValue==1) iInterface=iValue;
            if(i==7) if(iValue>=1 && iValue<=40) lGameSpeed=1000L*iValue;
            if(i==8) ikLeftAH=iValue;
            if(i==9) ikLeftAL=iValue;
            if(i==10) ikRightAH=iValue;
            if(i==11) ikRightAL=iValue;
            if(i==12) ikDownAH=iValue;
            if(i==13) ikDownAL=iValue;
            if(i==14) ikChangeAH=iValue;
            if(i==15) ikChangeAL=iValue;
            if(i==16) if(iValue>=0 && iValue<MAXMODE) ColorMode=iValue;
            if(i>=17 && i<17+MAXMODE){
                for(j=0;j<16;j++){
                    cRight[0]=cLine[j*3];
                    cRight[1]=cLine[j*3+1];
                    cRight[2]=cLine[j*3+2];
                    iValue=atoi(cRight);
                    iCurColorMode[i-17][j]=iValue;
             }
                cRight[2]='/0';
                for(j=0;j<11;j++){
                    cRight[0]=cLine[48+j*2];
                    cRight[1]=cLine[48+j*2+1];
                    iValue=atoi(cRight);
                    iColorValue[i-17][j]=iValue;
             }
         }
        };
    }
    fclose(fp);
}
/****************************** SaveUserInfo ****************************/
void SaveUserInfo(){
    int i,j;
    FILE * fp;
    fp=fopen("tetris.ini","w");
    if(!fp==NULL){      /* OK */
        /* Option */
        fprintf(fp,"Adv Mode=%2d/n",iAdvMode);
        fprintf(fp,"Random Color=%2d/n",iRandomColor);
        fprintf(fp,"Init Speed=%2d/n",iInitSpeed);
        fprintf(fp,"Init Level=%2d/n",iInitLevel);
        fprintf(fp,"Box Style=%2d/n",iBoxStyle);
        fprintf(fp,"Interface=%2d/n",iInterface);
        fprintf(fp,"Game speed=%2d/n",(int)(lGameSpeed/1000));
        /* Key */
        fprintf(fp,"Left AH=%2d/n",ikLeftAH);
        fprintf(fp,"Left AL=%2d/n",ikLeftAL);
        fprintf(fp,"Right AH=%2d/n",ikRightAH);
        fprintf(fp,"Right AL=%2d/n",ikRightAL);
        fprintf(fp,"Down AH=%2d/n",ikDownAH);
        fprintf(fp,"Down AL=%2d/n",ikDownAL);
        fprintf(fp,"Change AH=%2d/n",ikChangeAH);
        fprintf(fp,"Change AL=%2d/n",ikChangeAL);
        /* Extend */
        fprintf(fp,"ColorMode=%2d/n",ColorMode);
        for(i=0;i<MAXMODE;i++){
            for(j=0;j<16;j++)
                fprintf(fp,"%3d",iCurColorMode[i][j]);
            for(j=0;j<10;j++)
                fprintf(fp,"%2d",iColorValue[i][j]);
            fprintf(fp,"%2d/n",iColorValue[i][j]);
        }
    }
    fclose(fp);
}
/******************************** MsgBox *********************************/
void MsgBox(int l,int t,int r,int b,char cMsg[81]){
    Button(l,t,r,b,iBgColor);
    settextjustify(1,1);
    setcolor(iForeColor);
    outtextxy(l+(r-l)/2,t+(b-t)/2,cMsg);   
}
/********************************** End **********************************/
void End(){
    free(vmImage);
    closegraph();
    SaveUserInfo();
    exit(0);
}
/******************************** OpenFile *******************************/
void OpenFile(){
    FILE * fp;
    char cLine[50];
    char cRight[8];
    int i,j,iValue,len;
    i=0;
    iFileName=FALSE;
    FrmGetFileName(OPENFILE);
    if(iFileName){
        fp=fopen(cFileName,"r");
        if(fp!=NULL){
            MsgBox(box[1][1].x,220,box[1][9].x,260,"Loading...");
        while(fgets(cLine,50,fp)){
            len=strlen(cLine);
            cRight[0]=cLine[len-3];
            cRight[1]=cLine[len-2];
            cRight[2]='/0';
            iValue=atoi(cRight);
            i++;
            if(i==1) if(iValue==0 || iValue==1) iAdvMode=iValue;
            if(i==2) if(iValue==0 || iValue==1) iRandomColor=iValue;
            if(i==3) if(iValue>=0 && iValue<=MAXSPEED) iInitSpeed=iValue;
            if(i==4) if(iValue>=0 && iValue<=MAXSPEED) iInitLevel=iValue;
            if(i==5) if(iValue>=1 && iValue<=40) lGameSpeed=1000L*iValue;
            if(i==6) if(iValue>=1 && iValue<=15) iCurNum=iValue;
            if(i==7) if(iValue>=1 && iValue<=4) iCurShape=iValue;
            if(i==8) if(iValue>=0 && iValue<iMaxColor) iCurColor=iValue;
            if(i==9) if(iValue>=1 && iValue<=15) iNextNum=iValue;
            if(i==10) if(iValue>=1 && iValue<=4) iNextShape=iValue;
            if(i==11) if(iValue>=0 && iValue<iMaxColor) iNextColor=iValue;
            if(i==12) if(iValue>=0 && iValue<ROW) iCurRow=iValue;
            if(i==13) if(iValue>=0 && iValue<COL) iCurCol=iValue;
            if(i==14) if(iValue>=0 && iValue<=MAXSPEED) iSpeed=iValue;
            if(i==15) if(iValue>=0 && iValue<=MAXSPEED) iLevel=iValue;
            if(i==16) { /* Lines */
                for (j=0;j<4;j++)
                    cRight[j]=cLine[len-5+j];
                cRight[j]='/0';
                iValue=atoi(cRight);
                if(iValue>=0) iLines=iValue;
         }
            if(i==17){  /* Score */
                for (j=0;j<6;j++)
                    cRight[j]=cLine[len-7+j];
                cRight[j]='/0';
                lScore=atol(cRight);
                if(lScore < 0L) lScore=0;
         }
            if(i>=18 && i<18+ROW){
                cRight[2]='/0';
                for(j=0;j<COL;j++){
                    cRight[0]=cLine[j*4];
                    cRight[1]=cLine[j*4+1];
                    iValue=atoi(cRight);
                    box[i-18][j].have=iValue;
                    cRight[0]=cLine[j*4+2];
                    cRight[1]=cLine[j*4+3];
                    iValue=atoi(cRight);
                    box[i-18][j].color=iValue;
             }
         }
        };/* end while */
        strcpy(cGameStatus,"Pause");
        NewBox(-1);
        FrmMain();
        RefreshGameArea();
        ShowBox(SHOW,SHOW);
        StatusBar(TRUE,cMsg2);
        }/* end if fp */
        fclose(fp);
    }/* end if */
}
/******************************** SaveFile *******************************/
void SaveFile(){
    FILE * fp;
    int i,j;   
    iFileName=FALSE;
    strcpy(cGameStatus,"Pause");
    FrmGetFileName(SAVEFILE);
    if(iFileName){
        fp=fopen(cFileName,"w");
    if(fp!=NULL){
        /* Option */
        fprintf(fp,"Adv Mode=%2d/n",iAdvMode);
        fprintf(fp,"Random Color=%2d/n",iRandomColor);
        fprintf(fp,"Init Speed=%2d/n",iInitSpeed);
        fprintf(fp,"Init Level=%2d/n",iInitLevel);
        fprintf(fp,"Game speed=%2d/n",(int)(lGameSpeed/1000));
        /* */
        fprintf(fp,"CurNum=%2d/n",iCurNum);
        fprintf(fp,"CurShape=%2d/n",iCurShape);
        fprintf(fp,"CurColor=%2d/n",iCurColor);
        fprintf(fp,"NextNum=%2d/n",iNextNum);
        fprintf(fp,"NextShape=%2d/n",iNextShape);
        fprintf(fp,"NextColor=%2d/n",iNextColor);
        fprintf(fp,"CurRow=%2d/n",iCurRow);
        fprintf(fp,"CurCol=%2d/n",iCurCol);
        fprintf(fp,"Speed=%2d/n",iSpeed);
        fprintf(fp,"Level=%2d/n",iLevel);
        fprintf(fp,"Lines=%4d/n",iLines);
        fprintf(fp,"Score=%6ld/n",lScore);
        for (i=0;i<ROW;i++){
            for(j=0;j<COL-1;j++)
                fprintf(fp,"%2d%2d",box[i][j].have,box[i][j].color);
            fprintf(fp,"%2d%2d/n",box[i][j].have,box[i][j].color);
        }
    }
    fclose(fp);
    }
    StatusBar(TRUE,cMsg2);
}
/****************************** init_graph ***********************************/
void init_graph(){
    union REGS r;
    closegraph();
    r.h.ah=0;
    r.h.al=0x5f;
    int86(0x10,&r,&r);
    vgabase=(char far *)MK_FP(0xA000,0);
    curpage=0;
}
/**************************** set_page2 ***********************************/
void set_page(unsigned char page)
{
    union REGS in,out;
    in.x.bx=0;
    in.x.dx=page;
    in.x.ax=0x4F05;
    int86(0x10,&in,&out);
}
/******************************** pset ***********************************/
void pset(unsigned x,unsigned y,unsigned char color)
{
    char far *base;
    long address;
    unsigned char page=0;
    address=y*WIDTH+x;
    while(address>65536L)
    {
        page++;
        address-=65536L;
    }
    if(page!=curpage)
    {
        set_page(page);
        curpage=page;
    }
    base=(char far *)(vgabase+address);
    *base=color;
}
/******************************** pset **************************************/
void pset2(unsigned x,unsigned y,unsigned char color){
    union REGS r;
    r.h.ah=0xc;
    r.x.dx=y;
    r.x.cx=x;
    r.h.al=color;
    int86(0x10,&r,&r);
}
/***************************** gotoxy2 **************************************/
void gotoxy2(unsigned x,unsigned y){
    union REGS r;
    r.h.ah=2;
    r.h.bh=0;
    r.h.dl=y;
    r.h.dh=x;
    int86(0x10,&r,&r);
}
/********************************* printchar ********************************/
void printchar(unsigned x,unsigned y,unsigned char color,unsigned char  ch){
    union REGS r;
    gotoxy2(x,y);
    r.h.ah=0xe;
    r.h.bl=color;
    r.h.al=ch; 
    int86(0x10,&r,&r);
}
/******************************* printstring *******************************/
void printstring(unsigned x,unsigned y,unsigned char color,const char * string){
    union REGS r;
    gotoxy2(x,y);
    r.h.ah=0xe;
    r.h.bl=color;
    while(r.h.al=*string++)
        int86(0x10,&r,&r);
}
/********************************* line2 **********************************/
void line2(int l,int t,int r,int b,unsigned char bcolor,int fill){
    register int i,j;
    union REGS rr;
    rr.h.ah=0xc;
    rr.h.al=bcolor;
    if(!fill){
        for(i=l;i<=r;i++){
            pset(i,t,bcolor);
            pset(i,b,bcolor);
        }
        for(i=t;i<=b;i++){
            pset(l,i,bcolor);
            pset(r,i,bcolor);
        }
    }else
        for(i=l;i<=r;i++){
            rr.x.cx=i;
            for(j=t;j<=b;j++){
                rr.x.dx=j;
                int86(0x10,&rr,&rr);
                /*pset(i,j,bcolor);*/
         }
        }
}
/******************************** Show_Title ******************************/
void Show_Title(){
    char * title="Select Color";
    int i=0;
    while(*title)
        printchar(1,34+i,50+i++,*title++);
}
/****************************** Draw_AllColor *****************************/
void Draw_AllColor(){
    int i,j,x,y,wid,hei;
    unsigned l,t,r,b;
    char * str="000";
    int rownum=12;
    x=57,y=34;
    wid=12,hei=8;
    j=2;
    for(i=0;i<250;i++){
        if(i%rownum==0) j++;
        if(i==249)
            itoa(255,str,10);
        else
            itoa(i,str,10);
        if(i<10){
            str[2]=str[0];
            str[0]=' ';
            str[1]=' ';
        }
        if(i<100 && i>9){
            str[2]=str[1];
            str[1]=str[0];
            str[0]=' ';
        }
        printstring(j,i%rownum*6+4,15,str);
    }
    j=0;
    for(i=0;i<250;i++){
        if(i%12==0) j++;
        l=x+i%rownum*(wid+36),t=y+j*(hei+8);
        r=l+wid,b=t+hei;
        if(i==248){
            line2(l+2,t+4,r+4,t+4,100,0);
            continue;
        }
        line2(l,t,r,b,i,1);
        line2(l-1,t-1,r+1,b+1,15,0);
    }
}
/******************************* GetAllColors ********************************/
void GetAllColors(){
    int i;
    for(i=0;i<256;i++){
        outport(0x3c7,i);
        Color256[i].red=inportb(0x3c9);
        Color256[i].green=inportb(0x3c9);
        Color256[i].blue=inportb(0x3c9);   
    }
}
/****************************** drawcursor **********************************/
void drawcursor(int x,int y,int mode){
    static int xx,yy;
    int icolor;
    if(x>0) xx=x;
    if(y>0) yy=y;
    if(mode) icolor=46; else icolor=0;
    line2(xx,yy,xx,yy+13,icolor,0);
}
/***************************** SelectColor ***********************************/
int SelectColor(){
    int i,xx[8],y,ah,al;
    int row,col,iExitSelect=0,iFocus=0;
    int l,t,r,b,count,iCursor=1,len,iOverFlow=0;
    char * ctemp="000";
    int temp[16];
    init_graph();
    Show_Title();
    line2(0,0,639,479,100,0);
    Draw_AllColor();
    xx[0]=42;
    y=400;
    for(i=1;i<8;i++)
        xx[i]=xx[i-1]+72;
    row=25,col=4;
    for(i=0;i<16;i++){
        temp[i]=iCurColorMode[ColorMode][i];     /* copy */
        l=xx[i%8],t=y+i/8*32;
        r=l+16,b=t+15;
        line2(l,t,r,b,temp[i],1);
        line2(l-1,t-1,r+1,b+1,100,0);
        line2(l+20,t-1,r+32,b+1,100,0);
        itoa(temp[i],ctemp,10);
        printstring(row+i/8*2,col+i%8*9+4,100,ctemp);
    }
    printstring(row+4,col,100,"Tab:Skip     F6:Save&Exit    Esc:Exit ");
    line2(0,0,639,479,100,0);
    count=0;
    while(!iExitSelect){
        l=xx[iFocus%8]-4,t=y+iFocus/8*32-4;
        r=l+55,b=t+23;
        line2(l,t,r,b,45,0);
        while(!kbhit()){
            delay(lGameSpeed);
            count++;
            if(iOverFlow>0) iOverFlow++;
            if(iOverFlow>40){
                printstring(row+4,col+39,0,"Num is overflow! please enter agian.");
                line2(0,0,639,479,100,0);
                iOverFlow=0;
         }
            if(count>5){
                count=0;
                if(temp[iFocus]<0) len=0;
                else{
                    itoa(temp[iFocus],ctemp,10);
                    len=strlen(ctemp);
             }
                drawcursor(l+25+len*8,t+5,iCursor);
                iCursor=iCursor*-1+1;
         }
        }
        GetKey(&ah,&al);
        if(ah==1 && al==27) return 0;  /* ESC */
        if(ah==15 && al==9){                /* Tab */
            line2(l,t,r,b,0,0);
            if (temp[iFocus]<255) line2(l+4,t+4,l+20,t+19,temp[iFocus],1);
            drawcursor(-1,-1,0);
            iFocus++;
            if(iFocus>15) iFocus=0;
        }
        if(ah==64 && al==0){                /* F6 Save  */
            iOverFlow=0;
            for(i=0;i<16;i++)
                if(temp[i]>255) {           /* overflow */
                    printstring(row+4,col+39,13,"Num is overflow! please enter agian.");
                    line2(0,0,639,479,100,0);
                    drawcursor(-1,-1,0);
                    iFocus=i;
                    iOverFlow=1;
                    break;
             }
            if(!iOverFlow) {            /* Change Color */
                for(i=0;i<16;i++)
                    iCurColorMode[ColorMode][i]=temp[i];
                return 1;
         }
        }
        if(ah==14 && al==8){                /* BackSpace */
            drawcursor(-1,-1,0);
            if(temp[iFocus]>=0){
                itoa(temp[iFocus],ctemp,10);
                len=strlen(ctemp);
                line2(l+18+len*8,t+5,l+26+len*8,t+18,0,1);
                if(len==1)
                    temp[iFocus]=-1;
                else{
                    ctemp[len-1]='/0';
                    temp[iFocus]=atoi(ctemp);
             }
         }
        }
        if(al>=48 && al<=57 && temp[iFocus]<100){               /* 0--9 */
            drawcursor(-1,-1,0);
            if(temp[iFocus]<=0){
                ctemp[0]=al;
                len=0;
            }else{
                itoa(temp[iFocus],ctemp,10);
                len=strlen(ctemp);
                ctemp[len]=al;
         }
            ctemp[len+1]='/0';
            temp[iFocus]=atoi(ctemp);    
            printstring(row+iFocus/8*2,col+iFocus%8*9+4,100,ctemp);
        }
    }
}
/********************************* main **********************************/
void main(){
    Init();
    FrmMain();    
    Begin();
    End();
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用C语言俄罗斯方块的代码示例如下: ```c #include <stdio.h> #include <stdbool.h> #define HEIGHT 20 #define WIDTH 10 int board[HEIGHT][WIDTH] = {0}; typedef struct { int x; int y; } Point; typedef struct { Point blocks[4]; } Tetromino; Tetromino tetrominos[7] = { // I {{{0, 0}, {0, 1}, {0, 2}, {0, 3}}}, // J {{{0, 0}, {1, 0}, {1, 1}, {1, 2}}}, // L {{{0, 2}, {1, 0}, {1, 1}, {1, 2}}}, // O {{{0, 0}, {0, 1}, {1, 0}, {1, 1}}}, // S {{{0, 1}, {0, 2}, {1, 0}, {1, 1}}}, // T {{{0, 0}, {0, 1}, {0, 2}, {1, 1}}}, // Z {{{0, 0}, {0, 1}, {1, 1}, {1, 2}}}, }; bool is_valid_move(Tetromino tetromino, int x, int y) { for (int i = 0; i < 4; i++) { int new_x = x + tetromino.blocks[i].x; int new_y = y + tetromino.blocks[i].y; // Check if block is out of bounds if (new_x < 0 || new_x >= WIDTH || new_y < 0 || new_y >= HEIGHT) { return false; } // Check if block collides with another block if (board[new_y][new_x] != 0) { return false; } } return true; } void place_tetromino(Tetromino tetromino, int x, int y) { for (int i = 0; i < 4; i++) { int new_x = x + tetromino.blocks[i].x; int new_y = y + tetromino.blocks[i].y; board[new_y][new_x] = 1; } } void print_board() { for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { if (board[i][j] == 0) { printf(" "); } else { printf("■"); } } printf("\n"); } } int main() { Tetromino current_tetromino = tetrominos[0]; int x = 4; int y = 0; while (true) { // Check if current position is valid if (!is_valid_move(current_tetromino, x, y)) { // Place tetromino on the board place_tetromino(current_tetromino, x, y); // Check for completed lines and remove them // ... // Spawn a new tetromino current_tetromino = tetrominos[1]; x = 4; y = 0; } // Update game state // ... // Render game state print_board(); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值