#include <io.h>
#include <system.h>
#include <stdio.h>

#define IOWR_VGA_DATA(base, offset, data) \
    IOWR_32DIRECT(base, (offset) * 4, data)

#define speed 1

#define origin_x 18
#define origin_y 36

#define op 4

#define type_sred 13
#define type_lred 15
#define type_sgreen 9
#define type_lgreen 11 
#define type_sblue 1
#define type_lblue 3
#define type_sorange 5
#define type_lorange 7
#define type_explode 21
#define type_start 24
#define type_pause 25
#define type_next 26
#define type_back 27
#define type_begin 41
#define type_fail 42
#define type_win 43
#define type_blank 45

#define type_up 17
#define type_down 18
#define type_left 19
#define type_right 20

#define type_lv 29
#define type_hit 30

#define type_0 31
#define type_1 32
#define type_2 33
#define type_3 34
#define type_4 35
#define type_5 36
#define type_6 37
#define type_7 38
#define type_8 39 
#define type_9 40 

#define snum1 1
#define snum2 9
#define snum3 1
#define snum4 13
#define snum5 13
#define snum6 17
#define snum7 14
#define snum8 15
#define snum9 14 
#define snum10 9

#define tap_left1 1
#define tap_left2 1
#define tap_left3 2
#define tap_left4 3
#define tap_left5 3
#define tap_left6 4
#define tap_left7 4
#define tap_left8 3
#define tap_left9 3
#define tap_left10 2

#define x_offset 18

//=========================structure def=========================
struct snapper{
  int x;
  int y;
  int num;
  int type;
  int pointed;
};

struct bullet{
   int x;
   int y;
   int num;
   int type;
   int init_x; 
   int init_y; 
};
 
struct pointer{
     int x;
     int y;
 };
 
//================================================================

struct snapper s1[1]={{162,180,1,type_sred,0}};

struct snapper s2[9]={{162,36,1,type_sred,0},
                      {306,36,2,type_sred,0},            
                      {90,108,3,type_sred,0}, 
                      {234,108,4,type_sred,0},
                      {162,252,5,type_sred,0},  
                      {18,324,6,type_sred,0}, 
                      {234,324,7,type_sred,0}, 
                      {90,396,8,type_sred,0},
                      {306,396,9,type_sred,0}};


               
struct snapper s3[1]={{162,180,1,type_sgreen,0}};

struct snapper s4[13]={{18,36,1,type_sred,0},
                       {306,36,2,type_sred,0},
                       {18,108,3,type_sgreen,0},
                       {90,108,4,type_sgreen,0},
                       {162,108,5,type_sgreen,0},
                       {234,108,6,type_sgreen,0},
                       {306,108,7,type_sgreen,0},
                       {18,180,8,type_sred,0},
                       {90,180,9,type_sred,0},
                       {162,180,10,type_sorange,0},
                       {234,180,11,type_sred,0},
                       {306,180,12,type_sred,0},
                       {162,252,13,type_sred,0}};
                       
struct snapper s5[13]={{90,36,1,type_sred,0},
                       {162,36,2,type_sred,0},
                       {234,36,3,type_sred,0},
                       {18,108,4,type_sred,0},
                       {90,108,5,type_sred,0},
                       {234,108,6,type_sred,0},
                       {306,108,7,type_sred,0},
                       {18,180,8,type_sblue,0},
                       {90,180,9,type_sred,0},
                       {234,180,10,type_sred,0},
                       {306,180,11,type_sblue,0},
                       {90,252,12,type_sred,0},
                       {234,252,13,type_sred,0}};
                       
struct snapper s6[17]={{18,36,1,type_sred,0},
                       {90,36,2,type_sgreen,0},
                       {162,36,3,type_sgreen,0},
                       {234,36,4,type_sred,0},
                       {306,36,5,type_sred,0},
                       {162,108,6,type_sgreen,0},
                       {234,108,7,type_sgreen,0},
                       {306,108,8,type_sgreen,0},
                       {18,180,9,type_sred,0},
                       {162,180,10,type_sred,0},
                       {234,180,11,type_sred,0},
                       {306,180,12,type_sgreen,0},
                       {162,252,13,type_sgreen,0},
                       {234,252,14,type_sgreen,0},
                       {90,324,15,type_sblue,0},
                       {162,324,16,type_sgreen,0},
                       {234,324,17,type_sgreen,0}};

struct snapper s7[14]={{18,36,1,type_sgreen,0},
                       {90,36,2,type_sred,0},
                       {234,36,3,type_sred,0},
                       {306,36,4,type_sgreen,0},
                       {90,108,5,type_sgreen,0},
                       {234,108,6,type_sgreen,0},
                       {90,180,7,type_sred,0},
                       {162,180,8,type_sgreen,0},
                       {234,180,9,type_sred,0},
                       {90,252,10,type_sblue,0},
                       {162,252,11,type_sred,0},
                       {234,252,12,type_sblue,0},
                       {18,324,13,type_sred,0},
                       {306,324,14,type_sred,0}};
                       
struct snapper s8[15]={{162,36,1,type_sred,0},
                       {18,108,2,type_sgreen,0},
                       {162,108,3,type_sred,0},
                       {306,108,4,type_sgreen,0},
                       {18,252,5,type_sgreen,0},
                       {90,252,6,type_sorange,0},
                       {162,252,7,type_sred,0},
                       {234,252,8,type_sorange,0},
                       {306,252,9,type_sgreen,0},
                       {18,324,10,type_sgreen,0},
                       {90,324,11,type_sgreen,0},
                       {162,324,121,type_sgreen,0},
                       {234,324,13,type_sgreen,0},
                       {306,324,14,type_sgreen,0},
                       {162,396,15,type_sgreen,0}};
                       
struct snapper s9[14]={{18,36,1,type_sgreen,0},
                       {162,36,2,type_sred,0},
                       {306,36,3,type_sgreen,0},
                       {90,108,4,type_sred,0},
                       {162,108,5,type_sgreen,0},
                       {234,108,6,type_sred,0},
                       {18,252,7,type_sred,0},
                       {162,252,8,type_sblue,0},
                       {306,252,9,type_sred,0},
                       {18,324,10,type_sgreen,0},
                       {306,324,11,type_sgreen,0},
                       {90,396,12,type_sred,0},
                       {162,396,13,type_sorange,0},
                       {234,396,14,type_sred,0}};
                       
struct snapper s10[9]={{162,36,1,type_sgreen,0},
                       {18,108,2,type_sred,0},
                       {90,108,3,type_sgreen,0},
                       {306,108,4,type_sred,0},
                       {18,180,5,type_sred,0},
                       {90,180,6,type_sgreen,0},
                       {162,180,7,type_sred,0},
                       {306,180,8,type_sred,0},
                       {90,252,9,type_sred,0}};                   


struct snapper *pointed;
struct bullet *upcnt;
struct bullet *downcnt;                    
struct bullet *leftcnt;
struct bullet *rightcnt;

int bcnt;
int snum;
int level;
int tap_left;
int upstop=0;
int downstop=0;
int leftstop=0;
int rightstop=0;
int flag2=0;

//assemble the data and send, for snappers 
void swd(struct snapper *s){
    int wd;
    int ad;
    wd=(s->num<<20)+(s->y<<10)+s->x;   
    ad=(s->type<<5)+0;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
} 

//assemble the data and send, for bullets 
void bwd(struct bullet *b){
    int wd;
    int ad;
    wd=(b->num<<20)+(b->y<<10)+b->x;  
    ad=(b->type<<5)+1;    
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
}


void show_level(){
    int wd;
    int ad;
    int type=type_lv;
    int num_level=1;
    int num_nlevel=2;
    int type_nlevel;
    int lx=400;
    int ly=10;
    int lnx=435;
    int lny=10;
    
    switch(level){
        case 0:
           type_nlevel=type_0;
           break;
        case 1:
           type_nlevel=type_1;
           break;    
        case 2:
           type_nlevel=type_2;
           break;
        case 3:
           type_nlevel=type_3;
           break;
        case 4:
           type_nlevel=type_4;
           break;
        case 5:
           type_nlevel=type_5;
           break;
        case 6:
           type_nlevel=type_6;
           break;
        case 7:
           type_nlevel=type_7;
           break;
        case 8:
           type_nlevel=type_8;
           break;
        case 9:
           type_nlevel=type_9;
           break;      
    }
    wd=(num_level<<20)+(ly<<10)+lx;
    ad=type<<5;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
    wd=(num_nlevel<<20)+(lny<<10)+lnx;
    ad=type_nlevel<<5;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
}   

void show_hit(){
    int wd;
    int ad;
    int type=type_hit;
    int num_hit=3;
    int num_nhit=4;
    int type_nhit;
    int hx=510;
    int hy=10;
    int hnx=545;
    int hny=10;
    
    switch(tap_left){
        case 0:
           type_nhit=type_0;
           break;
        case 1:
           type_nhit=type_1;
           break;    
        case 2:
           type_nhit=type_2;
           break;
        case 3:
           type_nhit=type_3;
           break;
        case 4:
           type_nhit=type_4;
           break;
        case 5:
           type_nhit=type_5;
           break;
        case 6:
           type_nhit=type_6;
           break;
        case 7:
           type_nhit=type_7;
           break;
        case 8:
           type_nhit=type_8;
           break;
        case 9:
           type_nhit=type_9;
           break;      
    }
    wd=(num_hit<<20)+(hy<<10)+hx;
    ad=type<<5;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
    wd=(num_nhit<<20)+(hny<<10)+hnx;
    ad=type_nhit<<5;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
}  

void show_pointer(struct pointer *p){
    int wd;
    int ad=2;
    wd=((p->y+28)<<10)+(p->x+20);
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
}

int begin_x=200;
int begin_y=200;
int fail_x=300;
int fail_y=300;
int win_x=400;
int win_y=400;

void show_label(int type){
    int wd;
    int ad;
    int x;
    int y;
    switch(type){
        case type_begin:
             x=begin_x;
             y=begin_y;

        case type_fail:
             x=fail_x;
             y=fail_y;
        case type_win:
             x=win_x;
             y=win_y; 
    }
    wd=(y<<10)+x;
    ad=(type<<5)+4;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
}

void show_press_enter(){
    int wd=0;
    int ad=5;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);

}
 
void show_button_explain(){
    int wd=0;
    int ad=6;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);

} 
 

void show_buttons(){
    int wd;
    int ad;
    int x=435;
    int y=50;
    int type=type_start;
    int num=1;
    /*
    wd=(s->num<<20)+(s->y<<10)+s->x;   
    ad=(s->type<<5)+0;
    */
    wd=(num<<20)+(y<<10)+x;
    ad=(type<<5)+0;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
    num++;
    x=x+45;
    type=type_pause;
    wd=(num<<20)+(y<<10)+x;
    ad=(type<<5)+0;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
    num++;
    x=x+45;
    type=type_next;
    wd=(num<<20)+(y<<10)+x;
    ad=(type<<5)+0;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
    num++;
    x=x+45;
    type=type_back;
    wd=(num<<20)+(y<<10)+x;
    ad=(type<<5)+0;
    IOWR_VGA_DATA(VGA_RASTER_BASE, ad, wd);
} 
 
void expand(struct snapper *s, struct pointer *p){

        int i;
        for(i=0; i<snum; i++){
          if((p->x==(s+i)->x)&&(p->y==(s+i)->y)&&((s+i)->pointed==0)&&(s+i)->type!=type_explode){
           printf("s.type was %d\n",(s+i)->type);
           (s+i)->type=(s+i)->type+2;
           (s+i)->pointed=1;
           
           printf("s%d expanded, s.type=%d\n", i+1, (s+i)->type);
           swd(s+i);
           pointed=s+i;
           break; 
           }
        }  
    }


void contract(struct snapper *p){
    if(p->pointed==1){
        p->type=p->type-2;
        p->pointed=0;
        printf("p.type=%d\n",p->type);
        swd(p);
        printf("snapper is contracted.\n");
    }
}


void clear_screen(struct snapper *s){
    
    int num;
    int i;
    switch(level){
        case 0:
            snum=snum1;
            
            break;
        case 1:
            snum=snum2;
            
            break;
        case 2:
            snum=snum3;
            
            break;
        case 3:
            snum=snum4;
            
            break;
        case 4:
            snum=snum5;
          
            break;
        case 5:
            snum=snum6;
            
            break;
        case 6:
            snum=snum7;
            
            break;
        case 7:
            snum=snum8;
           
            break;
        case 8:
            snum=snum9;
            
            break;
        case 9:
            snum=snum10;
            
            break;
    }    
    //printf("snum=%d",snum);
    for(i=0; i<num; i++){
          
          s->type=type_blank;
          //printf("s.num=%d  ", s->num);
          //printf("cleaning s.type=%d  ", s->type);
          swd(s);
          s++;
      }
 
}


void print_btype(struct bullet *b){
    switch(b->type){
        case type_up: printf("(up)");
                 break;
        case type_down: printf("(down)");
                 break;
        case type_left: printf("(left)");
                 break;
        case type_right: printf("(right)");
                 break;

    }
}



void explode_init(struct snapper *s, struct bullet *b1, struct bullet *b2, struct bullet *b3, struct bullet *b4){
             
             b1->init_x=s->x+12;
             b1->init_y=s->y-12;
             b1->x=s->x+12;
             b1->y=s->y-12;
             b1->type=type_up;
             bcnt++;
             b1->num=bcnt;                                       
             
             printf("generate b%d.x=%d, ", b1->num-snum-1, b1->x);
             printf("b%d.y=%d, ", b1->num-snum-1, b1->y);
             print_btype(b1);
             printf("\n");

             
             b2->init_x=s->x+12;
             b2->init_y=s->y+38;
             b2->x=s->x+12;
             b2->y=s->y+38; 
             b2->type=type_down;
             bcnt++;
             b2->num=bcnt;                                             
            
             printf("generate b%d.x=%d, ", b2->num-snum-1, b2->x);
             printf("b%d.y=%d, ", b2->num-snum-1, b2->y);
             print_btype(b2);
             printf("\n");
             
             b3->init_x=s->x+12;
             b3->init_y=s->y+15;
             b3->x=s->x-12;
             b3->y=s->y+15;
             b3->type=type_left;
             bcnt++;
             b3->num=bcnt;
             printf("generate b%d.x=%d, ", b3->num-snum-1, b3->x);
             printf("b%d.y=%d, ", b3->num-snum-1, b3->y);
             print_btype(b3);
             printf("\n");
             
             b4->init_x=s->x+34;
             b4->init_y=s->y+15;
             b4->x=s->x+34;
             b4->y=s->y+15;
             b4->type=type_right;
             bcnt++;
             b4->num=bcnt;
            
             printf("generate b%d.x=%d, ", b4->num-snum-1, b4->x);
             printf("b%d.y=%d, ", b4->num-snum-1, b4->y);
             print_btype(b4);
             printf("\n");
             //printf("four bullets initial position received\n");
             
}

void hit(struct snapper *s, struct bullet *b){
     if(s->type!=type_explode&&b->type!=type_blank&&s->type!=type_blank){
     switch(b->type){
        case type_up: // up bullet
          
          if((s->y)>b->y&&s->x==((b->x)-12)&&b->init_y>s->y&&s!=pointed){
             
             printf("s%d hit by b%d ", s->num, b->num-snum-1);
             print_btype(b);
             printf("\n");
             
             if(s->type!=type_sred&&s->type<16){
                s->type=s->type+4;                                        
                printf("changed type to %d\n", s->type);
                swd(s);
                b->type=type_blank;
                printf("kill b%d",b->num-snum-1);
                print_btype(b);
                printf("\n");
                bwd(b); 
             }
             else if(s->type==type_sred)// red explodes
                {
                 b->type=type_blank;
                 bwd(b);
                 s->type=type_explode; 
                 swd(s); 
                 //for(i=0; i<1000; i++);
                 //s->type=type_btype_bnnlanktype_bnnlanktype_bnnlanktype_bnnlanktype_bnnlanknnlank;
                 //swd(s);
                 printf("explode by b%d ",b->num-snum-1);
                 print_btype(b);
                 printf("\n");
                 upcnt++;
                 downcnt++;
                 leftcnt++;
                 rightcnt++;   
                 explode_init(s,upcnt,downcnt,leftcnt,rightcnt);             //////?
                 
                }
          }
              
          break;
        case type_down: //down bullet 
        // printf("s->x=%d  b->x=%d\n", s->x, b->x);
         //printf("s->y=%d  b->y=%d\n", s->y, b->y);
         if(s->y<b->y&&s->x==((b->x)-12)&&b->init_y<s->y&&s!=pointed){
             printf("s%d hit by b%d ", s->num, b->num-snum-1);
             print_btype(b);
             if(s->type!=type_sred&&s->type<16){
                s->type=s->type+4;
                printf("changed type to %d\n", s->type);
                swd(s);
                b->type=type_blank; 
                printf("kill b%d",b->num-snum-1);
                print_btype(b);
                printf("\n");
                bwd(b);
             }
             else if(s->type==type_sred)// red explodes
                {
                 b->type=type_blank;
                 bwd(b);
                 s->type=type_explode;
                 swd(s); 
//                 for(i=0; i<1000; i++);
//                 s->type=type_blank;
//                 swd(s);
                 printf("explode by b%d ",b->num-snum-1);
                 print_btype(b);
                 printf("\n");
                 upcnt++;
                 downcnt++;
                 leftcnt++;
                 rightcnt++;   
                 explode_init(s,upcnt,downcnt,leftcnt,rightcnt);
                 
                }
          }
          
          break;
        case type_left:  //left bullet
           //printf("s->x=%d  left b->x=%d\n", s->x, b->x);
           //printf("s->y=%d  left b->y=%d\n", s->y, b->y);
           if(s->y==b->y-15&&s->x>(b->x)&&b->init_x>s->x&&s!=pointed){
              
             printf("s%d hit by b%d ", s->num, b->num-snum-1);
             print_btype(b);
            
             if(s->type!=type_sred&&s->type<16){
                s->type=s->type+4;
                printf("changed type to %d\n", s->type);
                
                swd(s);
                b->type=type_blank; 
                printf("kill b%d",b->num-snum-1);
                print_btype(b);
                printf("\n");
                bwd(b);
             }
             else if(s->type==type_sred)// red explodes
                {
                 b->type=type_blank;
                 bwd(b);
                 s->type=type_explode; 
                 swd(s);
//                 for(i=0; i<1000; i++);
//                 s->type=type_blank;
//                 swd(s);
                 printf("explode by b%d ",b->num-snum-1);
                 print_btype(b);
                 printf("\n");
                 upcnt++;
                 downcnt++;
                 leftcnt++;
                 rightcnt++;   
                 explode_init(s,upcnt,downcnt,leftcnt,rightcnt);
                 
                }
          }
          break;
        case type_right:  //right bullet
           //printf("s->x=%d  right b->x=%d\n", s->x, b->x);
           //printf("s->y=%d  right b->y=%d\n", s->y, b->y);
           if(s->y==(b->y-15)&&s->x==(b->x+10)&&b->init_x<s->x&&s!=pointed){
             printf("s%d hit by b%d ", s->num, b->num-snum-1);
             print_btype(b);
                     
             if(s->type!=type_sred&&s->type<16){
                s->type=s->type+4;
                printf("changed type to %d\n", s->type);
                swd(s);
                b->type=type_blank; 
                printf("kill b%d",b->num-snum-1);
                print_btype(b);
                printf("\n");
                bwd(b);
             }
             else if(s->type==type_sred)// red explodes
                {
                 b->type=type_blank;
                 s->type=type_explode;
                 swd(s);
                 bwd(b);
//                 for(i=0; i<1000; i++);
//                 s->type=type_blank;
//                 swd(s);
                 printf("explode by b%d ",b->num-snum-1);
                 print_btype(b);
                 printf("\n");

                 upcnt++;
                 downcnt++;
                 leftcnt++;
                 rightcnt++;   
                 explode_init(s,upcnt,downcnt,leftcnt,rightcnt);
                 
                }
          }
          break;
        
     }
    }
}


int stage_clear(struct snapper *s){
    int i;
    //printf("in stage_clear\n");
    
    for(i=0; i<snum; i++){
        //printf("examine the type: %d\n", (s+i)->type);
        if((s+i)->type!=type_explode)
           return 0;
    }
    printf("All snappers have been exploded\n");
    return 1;  
}

void game_over(struct snapper *s){
   clear_screen(s);   
  //***********************add game over picture here
}

void level_initialize(struct snapper *s){
     int i;
     struct snapper *sl;
     switch(level){
        
        case 0:
               sl=s1;
               snum=snum1;
               tap_left=tap_left1;
               break;     
        case 1:
               sl=s2;
               snum=snum2; 
               tap_left=tap_left2;
               break; 
                     
        case 2:
               sl=s3;
               snum=snum3; 
               tap_left=tap_left3; 
               break;     
        case 3:
               sl=s4;
               snum=snum4;  
               tap_left=tap_left4;  
               break;   
        case 4:
               sl=s5;
               snum=snum5;  
               tap_left=tap_left5;
               break;     
        case 5:
               sl=s6;
               snum=snum6;  
               tap_left=tap_left6;
               break;     
        case 6:
               sl=s7;
               snum=snum7; 
               tap_left=tap_left7; 
               break;     
               
        case 7:
               sl=s8;
               snum=snum8;    
               tap_left=tap_left8;
               break; 
        case 8:
               sl=s9;
               snum=snum9;   
               tap_left=tap_left9; 
               break;    
        case 9:
               sl=s10;
               snum=snum10; 
               tap_left=tap_left10; 
               break;    
                 
     }
     //printf("snum=%d\n", snum);
    for(i=0; i<snum ;i++){
        
        s->x=(sl+i)->x;
        s->y=(sl+i)->y;
        s->num=(sl+i)->num+op;
        //printf("%d ",s->num);
        s->type=(sl+i)->type;
        s->pointed=0;
        swd(s);
        s++;
        
    }
    bcnt=op+snum+1;
    
}


//*******************MAIN***************************
int main(){
  /*
  int upstop=0;
  int downstop=0;
  int leftstop=0;
  int rightstop=0;
  */
  int cc=0;
  int i=0;
  int flg=1;
  int tone=3;
  int delay=1;
  int release=0;
  printf("Hello :D\n");
  unsigned char code,read;
  IOWR_16DIRECT(AUDIO_BASE,0,(tone*256));
  
  //***********struct snapper(x,y,num,type,pointed)************
  
  //***********struct bullet(x,y,num,type, init_x, init_y)*********************

//=================snappers initialization
  struct snapper s[17]={{-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0},
                       {-1,-1,-1,-1,0}};
                      

  //================bullets initialization
  struct bullet up[10]={{-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1},
                        {-1,-1,0,type_up,-1,-1}};

  upcnt=up-1;

  struct bullet down[10]={{-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1},
                          {-1,-1,0,type_down,-1,-1}};
  
  
  downcnt=down-1;

  struct bullet left[10]={{-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1},
                          {-1,-1,0,type_left,-1,-1}};
  leftcnt=left-1;
  
  struct bullet right[10]={{-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1},
                           {-1,-1,0,type_right,-1,-1}};
  rightcnt=right-1;
  //show_label(type_begin);
  //show_press_enter();
  //show_button_explain();
  //show_buttons();
  level=3;
  level_initialize(s);
  show_level();
  show_hit();
  
  //clear_screen();
  
  struct bullet *bit;
  //=====================================
  
  struct pointer p1={origin_x, origin_y};
  printf("pointer x=%d y=%d\n",p1.x, p1.y);
  show_pointer(&p1);
  
  while(1){
   expand(s,&p1);
   printf("upstop=%d, ", upstop);
   printf("downstop=%d, ", downstop);
   printf("leftstop=%d, ", leftstop);
   printf("rightstop=%d\n", rightstop);
   //printf("upcnt=%d ", upcnt);
  // printf("up=%d ", up);
   while(upcnt>up-1&&(upstop==0||downstop==0||leftstop==0||rightstop==0)){
        cc++;
        printf("cc=%d",cc);
        //printf("There are bullets.\n");
        for(bit=upcnt; bit>up-1; bit--){
            printf("in!!  ");
            if(bit->type!=type_blank){
               
               printf("b%d.x=%d, ", bit->num-snum-1, bit->x);
               printf("b%d.y=%d, ", bit->num-snum-1, bit->y);
               print_btype(bit);
               printf("\n");
              
               bit->y=bit->y-speed;
               if(bit->y<20){
                  printf("b%d hits wall",bit->num-snum-1);
                  print_btype(bit);    
                  printf("\n");
                  bit->type=type_blank;  
                  bwd(bit);
               }
               else{
                  
                  bwd(bit);
                  for(i=0; i<snum; i++){
                   
                    hit((s+i),bit);  
               }
              
            }
        }   
            //for(i=0; i<1000; i++);           
        }
        
       for(bit=downcnt; bit>down-1; bit--){
            if(bit->type!=type_blank){
              
               printf("b%d.x=%d, ", bit->num-snum-1, bit->x);
               printf("b%d.y=%d, ", bit->num-snum-1, bit->y);
               print_btype(bit);
               printf("\n");
              
               bit->y=bit->y+speed;
               if(bit->y>460){
                  
                  printf("b%d hits wall",bit->num-snum-1);
                  print_btype(bit);
                  printf("\n");
                  bit->type=type_blank;  
                  bwd(bit);
               }
               else{
                  bwd(bit);
                  for(i=0; i<snum; i++){
                    
                     hit((s+i),bit);  
               }
              
            }
        }   
            //for(i=0; i<1000; i++);           
        }
        
        
         for(bit=leftcnt; bit>left-1; bit--){
            if(bit->type!=type_blank){
             
               printf("b%d.x=%d, ", bit->num-snum-1, bit->x);
               printf("b%d.y=%d, ", bit->num-snum-1, bit->y);
               print_btype(bit);
               printf("\n");
            
               bit->x=bit->x-speed;
               if(bit->x<10){
                  printf("b%d hits wall",bit->num-snum-1);
                  print_btype(bit);
                  printf("\n");
                  bit->type=type_blank;  
                  bwd(bit);
               }
               else{
                  bwd(bit);
                  for(i=0; i<snum; i++){
                    
                     hit((s+i),bit);  
               }
              
            }
        }   
            //for(i=0; i<1000; i++);           
        }
        
         for(bit=rightcnt; bit>right-1; bit--){
            if(bit->type!=type_blank){
             
               printf("b%d.x=%d, ", bit->num-snum-1, bit->x);
               printf("b%d.y=%d, ", bit->num-snum-1, bit->y);
               print_btype(bit);
               printf("\n");
             
               bit->x=bit->x+speed;
               if(bit->x>340){
                  printf("b%d hits wall",bit->num-snum-1);
                  print_btype(bit);
                  printf("\n");
                  bit->type=type_blank;  
                  bwd(bit);
               }
               else{
                  
                  bwd(bit);
                  for(i=0; i<snum; i++){
                    
                     hit((s+i),bit);  
               }
              
            }
        }   
            //for(i=0; i<1000; i++);           
        }
        
        //////////////////////////
       for(bit=upcnt; bit>up-1; bit--){
            
            if(bit->type!=type_blank){
               //printf("up_offset=%d, ",(bit-up));
               upstop=0; 
               //printf("******break\n"); 
               break;
            }        
       }
       
       if(bit==up-1){
          printf("bit= up -1")  ;
          //printf("check**********up_offset=%d\n",(bit-up));        
          upstop=1;  
       }
       /////////////////        
       for(bit=downcnt; bit>down-1; bit--){
            if(bit->type!=type_blank){
               downstop=0;
               break;
            }
       }
       if(bit==down-1){
          downstop=1; 
       }
       /////////////////   
       for(bit=leftcnt; bit>left-1; bit--){
            if(bit->type!=type_blank){
               leftstop=0;
               break;
            }
       }
       if(bit==left-1)
          leftstop=1; 
       ////////////////   
       for(bit=rightcnt; bit>right-1; bit--){
            if(bit->type!=type_blank){
               rightstop=0;
               break;
            }
       }
       if(bit==right-1)
          rightstop=1;
       /*
       printf("upstop=%d, ", upstop);
       printf("downstop=%d, ", downstop);
       printf("leftstop=%d, ", leftstop);
       printf("rightstop=%d\n", rightstop);   
      */
       for(i=0; i<7000; i++);

    }
  
 if(stage_clear(s)){
       printf("yuhan");
       clear_screen(s);
       pointed=0;
       level++;
       printf("***********************level up\n");
       level_initialize(s);
       show_level();
       show_hit();
       upstop=1;
       downstop=1;
       leftstop=1;
       rightstop=1;
       upcnt=up-1;
       downcnt=down-1;
       leftcnt=left-1;
       rightcnt=right-1;
       //printf("enter clear\n");
    }
   if(tap_left==0&&stage_clear(s)==0)
      game_over(s);
   
   
   while (!IORD_8DIRECT(PS2_BASE, 0)) ; /* Poll the status */
   code = IORD_8DIRECT(PS2_BASE, 4);
   //printf("code=%d\n",code);
   
   switch(code){
     case 240:
       release=1;
       break;
            
     //up
     case 117:
        if(release==1){
            tone=1;
            
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
            for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
          tone=3;
          IOWR_16DIRECT(AUDIO_BASE,0,(tone*256));
           //printf("up released\n");
           release=0;
           contract(pointed);

           if(p1.y>35){
              p1.y=p1.y-72;
              show_pointer(&p1);
           }
           printf("pointer: %d, %d\n", p1.x, p1.y);
        }
        break;
  
    //down
    case 114:
         if(release==1){
            tone=1;
            
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
            for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
          tone=3;
          IOWR_16DIRECT(AUDIO_BASE,0,(tone*256));
           //printf("down released\n");
           release=0;
           contract(pointed);
           
           if(p1.y<480-36){
              p1.y=p1.y+72;
              show_pointer(&p1);
           }
           printf("pointer: %d, %d\n", p1.x, p1.y);
        }
         break;

       
    
    
    //left
    case 107:
        if(release==1){
            tone=1;
           
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
            for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
          tone=3;
          IOWR_16DIRECT(AUDIO_BASE,0,(tone*256));
           //printf("left released\n");
           release=0;
           contract(pointed);
           
           if(p1.x>36){
              p1.x=p1.x-72;
              show_pointer(&p1);
           }
           printf("pointer: %d, %d\n", p1.x, p1.y);
        }
       break;
        
    //right
    case 116:
         if(release==1){
            tone=1;
            
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
            for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
          tone=3;
          IOWR_16DIRECT(AUDIO_BASE,0,(tone*256));
           //printf("right released\n");
           release=0;
           contract(pointed);

           if(p1.y<324){
              p1.x=p1.x+72;
              show_pointer(&p1);
           }
           printf("pointer: %d, %d\n", p1.x, p1.y);
        }
        break;
   //enter 
   case 90:
      if(release==1){
        tone=1;
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
            for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+14);
          for (delay=1; delay<10000; delay++) 
            IOWR_16DIRECT(AUDIO_BASE,0,(tone*256)+15); 
          tone=3;
          IOWR_16DIRECT(AUDIO_BASE,0,(tone*256));
        //printf("enter released\n");
        for(i=0; i<snum; i++){
            if((s+i)->pointed==1){
               tap_left--;       //************************minus tap here
               show_hit();
               printf("taps left:%d\n", tap_left);
               if((s+i)->type!=type_lred){ //not big red
                  (s+i)->type=(s+i)->type+4;
                  printf("s%d changes type to %d\n",i+1, (s+i)->type);
                  swd(s+i);
                  break;
               }
               else{
                   if((s+i)->type!=type_explode){  // red snapper explodes
                   printf("s%d wants to explode\n", i+1) ;
                   (s+i)->type=type_explode;
                   swd(s+i);
                   upcnt++;
                   //printf("after enter, upcnt=%d\n", upcnt);
                   downcnt++;
                   leftcnt++;
                   rightcnt++;
                   upstop=0;
                   downstop=0;
                   leftstop=0;
                   rightstop=0;
                   explode_init(s+i, upcnt, downcnt, leftcnt, rightcnt);
                   break;
                    }  
               }
            }
            
        }
      }  

      break;

    }
  }
  
  return 0;
}
