/*

	早撃ち! ver1.0

*/
#include<sys/bios.h>
#include<il_sound.h>
#include<resource.h>
#include<stdlib.h>
#include <fcntl.h>  
#include"pic01.h"

SoundIL soundIL;
extern BYTE *_heap;
extern void far *_resource;
 
char mb[100]="#0O3V10@0 e16d16e1";
char se1[50]="#1V8<c32>>c8";
char se2[50]="#2V5>>c32";
char se3[50]="#0V8<<c32>c16";

int speed[3][3]={{300,200,100},{70,50,30},{20,15,10}};

/*関数のプロトタイプ*/
int Menu(void);
int Game(int who);
int MusicInit(void);
int MusicPlay(int n,int mode);
int KeyCheck(void);
int DrawInit(void);
int DrawCls(int x,int y,int width,int height,int dis);
int GunmanDraw(int x, int y, int anime);
int TekiDraw(int x, int y, int anime, int syurui);
int NumDraw(int x, int y, int num);
int RankIn(int myscore);
int Ranking(void);
int MeGame(void);
int File(int rorw);

int i,j;/*ループカウンタ用*/

/*キー判定用*/
int keynow[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

/*画像の座標*/
int gunman1[4][2]={{80,81},{96,97},{112,113},{128,129}};
int gunman2[4][3]={{16,17,18},{32,33,34},{48,49,50},{64,65,66}};
int teki[3][2]={{10,11},{26,27},{42,43}};
int number[2]={144,160};
int kanban[5][5]={{69,70,71,72,73},{85,86,87,88,89},{101,102,103,104,105},{117,118,119,120,121},{133,134,135,136,137}};

int data[pic01_width * pic01_height];

int score[10]={999,999,999,999,999,999,999,999,999};

void far *res;
void far *se;

void main()
{
	int lp=0;
    
	if(MusicInit() == -1)
    	lp=-1;
    if(File(1)==-1)
    	lp=-1;
        
    while((key_press_check()&0x7fe));

	DrawInit();
    	
	while(lp == 0){
    
    	switch(Menu()){
        case 0:
        	Game(0);
        	break;
        case 1:
        	MeGame();
        	break;
        case 2:
        	Ranking();
        	break;
        case 3:
        	lp=-1;
        	break;
        }

		sys_wait(1);
	}

	File(0);

	sound_close();
	sounddrv_release();
}

int File(int rorw)
{
    int fd;
    
    
    chdir( "/ram0" );
    /* ファイルの作成 */
    if ( creat( "gundata", FMODE_R|FMODE_W, 1 ) == E_FS_SUCCESS ) {
        /* ファイル情報の設定 */
        fs_setinfo( "/ram0/gundata", "早撃ちデータ" );
    }
    if ( (fd = open( "gundata", O_RDWR, 0 )) >= 0 ) {
    	switch(rorw){
        case 0:
        	for(i=0; i<10; i++){
    			write( fd, &score[i], sizeof(score[i]) );
            }
            break;
        case 1:
        	for(i=0; i<10; i++){
        		read( fd, &score[i], sizeof(score[i]) );
            }
            break;
        }
        close( fd );
    } else {
        return -1;
    }
    
    return 0;
}

int Menu(void)
{
	int lp=0;
    static int koumoku=0;
    
    DrawCls(0,0,28,18,-1);
    
    keynow[2]=0;
    
    text_window_init(8, 2, 20, 3, 250);
    text_put_string(3, 0, "早撃ち！");
    text_put_string(0, 2, "〜ガンマンの野望〜");
    
    /* カーソルON */
    cursor_set_type( 1, 0 );
    cursor_display( 1 );
    cursor_set_location(9,9,9,1);
    
	while(lp == 0){
    	text_window_init(9, 9, 20, 7, 350);
        text_put_string(0, 0, "ライバルと早打ち！");
        text_put_string(0, 2, "自分と早打ち！");
        text_put_string(0, 4, "スコア");
        text_put_string(0, 6, "終了");
        
        KeyCheck();

		if(keynow[2]==3)
        	lp=-1;
        if(keynow[4]==3){
        	if(koumoku==0) koumoku=3;
        	else koumoku--;
        }
        if(keynow[6]==3){
        	if(koumoku==3) koumoku=0;
        	else koumoku++;
        }
        
        cursor_set_location(9,9+(koumoku*2),9,1);
		
        sys_wait(1);
    }
    
    while((key_press_check()&0x7fe));
    cursor_display(0);
    DrawCls(0,0,28,18,-1);
    
    switch(koumoku){
    case 0:
    	return 0;
        break;
    case 1:
    	return 1;
        break;
    case 2:
    	return 2;
        break;
    case 3:
    	return 3;
        break;
    }
}

int MeGame(void)
{
	int lp=0;
    int syouhai=0;
    int ute=0;
    static int wait=0;
    
    keynow[2]=0;
    
    DrawCls(0,0,28,18,-1);
    
    screen_fill_char(SCREEN1, 0, 0, 28, 18, data[7]);/*草を敷き詰める*/
    
    NumDraw(19,2,0);
    
    GunmanDraw(5,8,0);
    TekiDraw(20,9,0,2);
    
    MusicPlay(0,0);
    sys_wait(250);
    
    while(lp==0){
        
       	if(ute==1){
       		wait++;
           	if(wait==999){
           		keynow[2]=3;
               	ute=0;
           	}
           	if(wait==score[0]){
               	keynow[2]=3;
                ute=0;
            }
      	}
            
        NumDraw(19,2,wait);
                    
    	if(rand()%500 == 0 && ute==0){
           	MusicPlay(2,0);
       		TekiDraw(20,9,1,2);
           	ute=1;
       	}
        
       	KeyCheck();

		if(keynow[2]==3){
       		if(ute==0){
               	MusicPlay(1,0);
               	TekiDraw(20,9,2,2);
               	sys_wait(10);
               	TekiDraw(20,9,1,2);
               	sys_wait(75);
                MusicPlay(3,0);
           		GunmanDraw(5,8,1);
               	sys_wait(200);
               	syouhai=0;
               	lp=-1;
           	}
           	else if(ute==1){
               	RankIn(wait);
                MusicPlay(1,0);
           		GunmanDraw(5,8,2);
               	sys_wait(10);
               	GunmanDraw(5,8,3);
               	sys_wait(10);
               	GunmanDraw(5,8,2);
               	sys_wait(75);
                MusicPlay(3,0);
               	TekiDraw(20,9,3,2);
               	sys_wait(200);
               	syouhai=1;
               	lp=-1;
           	}
       	}
        
       	sys_wait(1);
    }
        
    wait=0;
    
    while ( (key_press_check()&0x7fe) ) ;  /* ボタンが放されるまで待つ */
    keynow[2]=0;
    DrawCls(0,0,28,18,-1);
    
    return 0;
}


int Ranking(void)
{
	text_screen_init();
    
    text_put_string(10, 3, "Ranking");
    
    for(i=0;i<9;i++){
    	text_put_numeric(10,6+i,1,NUM_PADZERO,i+1);
    	text_put_string(12, 6+i, ":");
    	text_put_numeric(14,6+i,3,NUM_PADZERO,score[i]);
    }
    
    key_wait();
    while ((key_press_check()&0x7fe));
   	DrawCls(0,0,28,18,-1);
    DrawInit();
    
    return 0;
}


/*
whoがLvを表す
*/
int Game(int who)
{
	int kati=0;
    static int make=0;
	static int lv=0;
    int lp2=0;
    lv=who;
    
    while(lp2==0){
		int lp=0;
    	int syouhai=0;
    	int ute=0;
    	static int wait=0;
    
    	keynow[2]=0;
        
        DrawCls(0,0,28,18,-1);
    
    	screen_fill_char(SCREEN1, 0, 0, 28, 18, data[7]);/*草を敷き詰める*/
    
    	NumDraw(19,2,0);
    
    	GunmanDraw(5,8,0);
    	TekiDraw(20,9,0,lv);
        
        text_window_init(0, 17, 28, 1, 400);
        for(i=0;i<make;i++){
        	text_put_string(i, 0, "×");	
        }
        for(i=0;i<kati;i++){
        	text_put_string(27-i, 0, "×");	
        }
    
    	MusicPlay(0,0);
    	sys_wait(250);
    
    	while(lp==0){
        
        	if(ute==1){
        		wait++;
            	if(wait==999){
            		keynow[2]=3;
                	ute=0;
            	}
               	if(wait==speed[lv][kati]){
                	keynow[2]=3;
                    ute=0;
                }
        	}
            
            NumDraw(19,2,wait);
                    
    		if(rand()%500 == 0 && ute==0){
            	MusicPlay(2,0);
        		TekiDraw(20,9,1,lv);
            	ute=1;
        	}
        
        	KeyCheck();

			if(keynow[2]==3){
        		if(ute==0){
                	MusicPlay(1,0);
                	TekiDraw(20,9,2,lv);
                	sys_wait(10);
                	TekiDraw(20,9,1,lv);
                	sys_wait(75);
                    MusicPlay(3,0);
            		GunmanDraw(5,8,1);
                	sys_wait(200);
                	syouhai=0;
                	lp=-1;
                    make++;
            	}
            	else if(ute==1){
                	RankIn(wait);
                    MusicPlay(1,0);
            		GunmanDraw(5,8,2);
                	sys_wait(10);
                	GunmanDraw(5,8,3);
                	sys_wait(10);
                	GunmanDraw(5,8,2);
                	sys_wait(75);
                    MusicPlay(3,0);
                	TekiDraw(20,9,3,lv);
                	sys_wait(200);
                	syouhai=1;
                	lp=-1;
                    kati++;
            	}
        	}
        
        	sys_wait(1);
    	}
        
        wait=0;
    
    	while((key_press_check()&0x7fe));
    	keynow[2]=0;
    	DrawCls(0,0,28,18,-1);
        
        if(kati==3){
        	text_window_init(10, 10, 20, 1, 350);
        	text_put_string(0, 0, "You Win!!");
            sys_wait(250);
            if(lv==2){
            	lp2=-1;
            }else{
            	Game(++lv);
                make=0;
                lv=0;
            	lp2=-1;
            }
        }else if(make==3){
        	text_window_init(10, 10, 20, 1, 350);
        	text_put_string(0, 0, "You Lose…");
            sys_wait(200);
            make=0;
            lv=0;
            lp2=-1;        
        }
	}
    return 0;
}

/*
ランクインの処理
*/
int RankIn(int myscore)
{
	for(i=0;i<9;i++){
    	if(myscore<score[i]){
        	for(j=9; j>i; j--){
           		score[j]=score[j-1];
            }
        	score[i]=myscore;
            return 1;
        }
    }
    return 0;
}

/*
数字を描く
*/
int NumDraw(int x, int y, int num)
{
    for(j=0;j<4;j++){
		for(i=0;i<2;i++){
        	switch(j){
    		case 0:
            	screen_set_char(SCREEN2,x+4-j,y+i,1, 1, &data[number[i]]+(num%10));
                break;
            case 1:
            	screen_set_char(SCREEN2,x+4-j,y+i,1, 1, &data[number[i]]+((num/10)%10));
                break;
            case 2:
            	screen_set_char(SCREEN2,x+4-j,y+i,1, 1, &data[number[i]]+32);
                break;
            case 3:
            	screen_set_char(SCREEN2,x+4-j,y+i,1, 1, &data[number[i]]+((num/100)%10));
                break;
            }
    	}
    }
    
    return 0;
}

/*
anime
0…通常
1…負け
2…銃1
3…銃2
*/
int GunmanDraw(int x, int y, int anime)
{
	switch(anime){
    case 0:
    	for(i=0;i<4;i++){
    		for(j=0;j<2;j++){
        		screen_set_char(SCREEN2,x+j,y+i,1, 1, &data[gunman1[i][j]]);
        	}
    	}
        break;
    case 1:
    	for(i=0;i<4;i++){
    		for(j=0;j<2;j++){
        		screen_set_char(SCREEN2,x+j,y+i,1, 1, &data[gunman1[i][j]]+2);
        	}
    	}
        break;
    case 2:
        for(i=0;i<4;i++){
    		for(j=0;j<3;j++){
        		screen_set_char(SCREEN2,x+j,y+i,1, 1, &data[gunman2[i][j]]);
        	}
    	}
    	break;
    case 3:
        for(i=0;i<4;i++){
    		for(j=0;j<3;j++){
        		screen_set_char(SCREEN2,x+j,y+i,1, 1, &data[gunman2[i][j]]+3);
        	}
    	}
    	break;
    }
    
    return 0;
}

/*
anime
0…普通
1…銃1
2…銃2
3…負け
syuruiで敵の種類
*/
int TekiDraw(int x,int y,int anime,int syurui)
{
    
    for(i=0;i<3;i++){
    	for(j=0;j<2;j++){
        	screen_set_char(SCREEN2,x+j,y+i,1, 1, &data[teki[i][j]]+(anime*16*3)+(syurui*2));
        }
    }

	return 0;
}

int DrawCls(int x,int y,int width,int height,int dis)
{
	/*矩形領域キャラクタ設定(P.105)*/
	if(dis==2 || dis==-1)
		screen_fill_char(SCREEN2, x, y, width, height, data[1]);

	if(dis==1 || dis==-1)
		screen_fill_char(SCREEN1, x, y, width, height, data[0]);
	return 0;
}

int DrawInit(void)
{
                       
	/*表示データアドレス(P.105)*/
	for(i = 0; i < (pic01_width * pic01_height); i++) data[i] = i | 4<<9;

	/*LCDカラー設定(P.112)*/
	lcd_set_color(0x7530, 0xFDB9);

	/*キャラクタカラー設定(P.112)*/
	palette_set_color(4, 0x7300);

	/*画面表示制御設定(P.101)*/
	display_control(DCM_SCR1 | DCM_SCR2 | DCM_SPR);

	/*カラーキャラクタ設定(P.102)*/
	font_set_colordata(0, pic01_width * pic01_height, bmp_pic01);

	/* スプライト登録(P.107)
	for( i = 0; i<5; i++) for( j=0; j<8; j++) sprite_set_char( j+118, data[masretu[j][i]] );

	スプライト表示許可範囲設定(P.106)
	sprite_set_range( 0, 40);*/

	return 0;
}

/*キーチェック関数
  引数
  	調べたいKey
  戻り値
   -1…エラー
  	0…離されている
    1…押されている
    2…離された瞬間
    3…押された瞬間
*/
int KeyCheck(void)
{
	int key=0;
    
    for(i=1;i<=11;i++){	
	    switch(i){
    	case 1:
        	key=KEY_START;
	        break;
	    case 2:
	        key=KEY_A;
	        break;
	    case 3:
	        key=KEY_B;
	        break;
	    case 4:
	        key=KEY_X1;
	        break;
	    case 5:
	        key=KEY_X2;
	        break;
	    case 6:
	        key=KEY_X3;
	       	break;
	    case 7:
	        key=KEY_X4;
	        break;
	    case 8:
	        key=KEY_Y1;
	        break;
	    case 9:
	        key=KEY_Y2;
	        break;
	    case 10:
	        key=KEY_Y3;
	        break;
	    case 11:
	        key=KEY_Y4;
	        break;
	    }
            
		if(key_press_check() & key){
			if(keynow[i]==0)
	        	keynow[i]=3;
	        else if(keynow[i]==3)
	        	keynow[i]=1;
		}
	    else{
			if(keynow[i]==1)
	        	keynow[i]=2;
	        else if(keynow[i]==2)
	        	keynow[i]=0;
	    }
    }
    
	/*key = key_press_check();*/
    return 0;
}

int MusicInit(void)
{
	if(open_sound_il(&soundIL) != E_FS_SUCCESS){
		/*ドライバが存在しない*/
		return -1;
	}

	sounddrv_init();
	sound_open();

	res = _pc->_resource;

	for(i=0; i<1; i++){
    	switch(((res_t far *)res)->type) { 
		case RESID_MUSIC:
			break;
    	case RESID_SE: 
      		se = (res_se_t far *)res; 
      		break; 
    	default: 
      		break; 
    	} 
		res = (BYTE far *)res + (((res_t far *)res)->size << 4); 
	}
	se_play(se,-1);

    return 0;
}

/*音を鳴らす関数
　n番目の音を鳴らす
　mode値が0ならMusic、1ならSe*/
int MusicPlay(int n,int mode){

	if(mode==0){
    	switch(n){
        case 0:
        	parse_mml(_heap,mb, 0);
        	break;
        case 1:
        	parse_mml(_heap,se1,0);
            break;
        case 2:
        	parse_mml(_heap,se2,0);
            break;
        case 3:
        	parse_mml(_heap,se3,0);
            break;
        }

    	bgm_play(_heap,0);
    }
    else if(mode==1){
    	se_play_n(n); /* n 番目の SE を鳴らす */
    }

    return 0;
}

                                                          