/************************************************
撞球探偵おけSOLO
という名の、似非ビリヤードゲーム

瀬野(webmaster@senobeya.com)
http://www.senobeya.com/witch/
*************************************************/

#include <sys/bios.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/libwwc.h>

#include "il_sound.h"
#include <resource.h>

#include "sincos.c"
#include "balls.h"
#include "biltitle_b.h"

/*
#include "bmpsaver.h"
*/

#define  ACCURACY 256
#define	 COUNTMAX 35


extern void far *_resource;
SoundIL soundIL;


long int abs(long int i);
void power_show(int power);


void main(){

struct ball_atr {
    unsigned long int x;
    unsigned long int  y;
    signed long int dx;
    signed long int dy;
    unsigned int flag;
};

/*
flagの構成
0:ボールがポケットしたか
1-9:衝突判定を行ったかどうか
*/


static struct ball_atr tama[10];
static struct ball_atr hit_tama[10];
unsigned int loop,mainloop;
unsigned int bk,k,i,ba,bb,count;
signed long int ddx,ddy;
signed int power;
int direction, range;
int shot_num;
int first_hit;

static unsigned int hasi[360];

/*
static char buf[30];
*/

	void far	*res = _pc->_resource;
	void far *se;
	
/************************************************
sound.IL初期化
*************************************************/

  if(open_sound_il(&soundIL) != E_FS_SUCCESS) { 
    text_put_string(0, 0, "sound driver not found"); 
    key_wait(); 
    bios_exit(); 
  } 
  sounddrv_init(); 
  sound_open();
  

/************************************************
リソースからサウンドファイル取得
*************************************************/

    se = (res_se_t far *)res; 
	res = (BYTE far *)res + (((res_t far *)res)->size << 4);
	se_play(se, -1);

/************************************************
カラーモード判定・設定
*************************************************/

    if ( wwc_get_hardarch() == HARDARCH_WS ) {
        text_screen_init();
        text_put_string( 1,1, "これはWonderSwanColor専用ソフトです" );
        text_put_string( 1,3, "旧WonderSwanでは実行できません" );
        key_wait();
        return;
    }

	wwc_set_color_mode( COLOR_MODE_16COLOR );
    wwc_clear_font();

/************************************************
タイトル表示
*************************************************/

	wwc_font_set_colordata(0,360,bmp_biltitle_b);

for(i=0;i<360;i++){
	hasi[i]=i;
}
screen_fill_char(SCREEN1,0,0,28,18,0);
    for ( i=0; i<16; i++ ) {
        wwc_palette_set_color( 0, i, palette_biltitle_b[i] );
	}

screen_set_char(SCREEN1,4,0,20,18,hasi);

	display_control(DCM_SCR1);

key_wait();


/************************************************
ゲーム関連フォント設定
*************************************************/

    wwc_font_set_colordata( 0, 64, bmp_balls );

    for ( i=0; i<16; i++ ) {
        wwc_palette_set_color( 0, i, palette_balls[i] );
        wwc_palette_set_color( 8, i, palette_balls[i] );
	}

/* ボール */
	
	for(i=0;i<10;i++){
		sprite_set_char(i,i+17);
	}

/* ターゲットカーソル */
	sprite_set_char(10,30);



/************************************************
画面描画
*************************************************/

screen_fill_char(SCREEN1,0,0,28,16,10);
screen_fill_char(SCREEN1,0,16,28,2,16);
screen_fill_char(SCREEN1,0,0,1,16,11);
screen_fill_char(SCREEN1,0,0,28,1,11);
screen_fill_char(SCREEN1,27,0,1,16,11);
screen_fill_char(SCREEN1,0,15,28,1,11);


hasi[0]=12;
hasi[1]=13;
hasi[2]=28;
hasi[3]=29;
screen_set_char(SCREEN1,0,0,2,2,hasi);


hasi[0]=13|CFM_FLIP_H;
hasi[1]=12|CFM_FLIP_H;
hasi[2]=29|CFM_FLIP_H;
hasi[3]=28|CFM_FLIP_H;
screen_set_char(SCREEN1,26,0,2,2,hasi);

hasi[0]=28|CFM_FLIP_V;
hasi[1]=29|CFM_FLIP_V;
hasi[2]=12|CFM_FLIP_V;
hasi[3]=13|CFM_FLIP_V;
screen_set_char(SCREEN1,0,14,2,2,hasi);

hasi[0]=29|CFM_FLIP_H|CFM_FLIP_V;
hasi[1]=28|CFM_FLIP_H|CFM_FLIP_V;
hasi[2]=13|CFM_FLIP_H|CFM_FLIP_V;
hasi[3]=12|CFM_FLIP_H|CFM_FLIP_V;
screen_set_char(SCREEN1,26,14,2,2,hasi);

hasi[0]=14|CFM_FLIP_V;
hasi[1]=15|CFM_FLIP_V;
screen_set_char(SCREEN1,13,0,2,1,hasi);

hasi[0]=14;
hasi[1]=15;
screen_set_char(SCREEN1,13,15,2,1,hasi);

hasi[0]=31;
hasi[1]=32;
hasi[2]=33;
hasi[3]=34;
hasi[4]=35;
hasi[5]=36;
hasi[6]=37;

screen_set_char(SCREEN1,0,17,7,1,hasi);

	display_control(DCM_SCR1 | DCM_SPR);


/************************************************
ボール初期位置設定。きちゃなー
*************************************************/


tama[0].x=3*8*ACCURACY;
tama[0].y=8*8*ACCURACY;
tama[0].dx=0;
tama[0].dy=0;

tama[1].x=160*ACCURACY;
tama[1].y=64*ACCURACY;

tama[6].x=166*ACCURACY;
tama[6].y=61*ACCURACY;
tama[5].x=166*ACCURACY;
tama[5].y=67*ACCURACY;

tama[4].x=172*ACCURACY;
tama[4].y=58*ACCURACY;
tama[9].x=172*ACCURACY;
tama[9].y=64*ACCURACY;
tama[2].x=172*ACCURACY;
tama[2].y=70*ACCURACY;

tama[8].x=178*ACCURACY;
tama[8].y=61*ACCURACY;
tama[7].x=178*ACCURACY;
tama[7].y=67*ACCURACY;

tama[3].x=184*ACCURACY;
tama[3].y=64*ACCURACY;


/*デカいボール用。未使用かなー

tama[0].x=3*8*ACCURACY;
tama[0].y=8*8*ACCURACY;
tama[0].dx=0;
tama[0].dy=0;

tama[1].x=160*ACCURACY;
tama[1].y=64*ACCURACY;

tama[6].x=168*ACCURACY;
tama[6].y=60*ACCURACY;
tama[5].x=168*ACCURACY;
tama[5].y=68*ACCURACY;

tama[4].x=176*ACCURACY;
tama[4].y=56*ACCURACY;
tama[9].x=176*ACCURACY;
tama[9].y=64*ACCURACY;
tama[2].x=176*ACCURACY;
tama[2].y=72*ACCURACY;

tama[8].x=184*ACCURACY;
tama[8].y=60*ACCURACY;
tama[7].x=184*ACCURACY;
tama[7].y=68*ACCURACY;

tama[3].x=192*ACCURACY;
tama[3].y=64*ACCURACY;
*/

for(i=0;i<10;i++){
sprite_set_location(i,tama[i].x/ACCURACY-4,tama[i].y/ACCURACY-4);
}
sprite_set_location(10,0,150);



/************************************************
メインルーチンスタート。
*************************************************/
shot_num=0;
mainloop=1;

while(mainloop){


/************************************************
射出位置設定 方向とパワーを設定したい。
押しだま、引きだまはどうするの？＜またこんど（ぉ
*************************************************/

k=0xFFFF;
loop=1;
power=0;
direction=0;
first_hit=0;
range=20;


sprite_set_range(0,11);

se_play_n(0);

while(loop){

bk=k;
k=key_press_check();

/* Aボタンで射出*/
	if((k&KEY_A)&&!(bk&KEY_A)){
		loop=0;
	}

/* Bボタンを押していると、球の番号がわかる。*/

	if((k&KEY_B)&&!(bk&KEY_B)){
		for(i=1;i<10;i++){
			sprite_set_char(i,i+38);
		}
	}
	if(!(k&KEY_B)&&(bk&KEY_B)){
		for(i=1;i<10;i++){
			sprite_set_char(i,i+17);
		}
	}

if(k&KEY_START){
	loop=0;
	mainloop=0;
}

	if(k&KEY_UP2 && shot_num==0){
		tama[0].y-=8;
		if(tama[0].y<24*ACCURACY){
			tama[0].y=24*ACCURACY;
		}
	}

	if(k&KEY_DOWN2 && shot_num==0 ){
		tama[0].y+=8;
		if(tama[0].y>104*ACCURACY){
			tama[0].y=104*ACCURACY;
		}
	}

	if(k&KEY_LEFT1){
		direction++;
		if(direction==7200){
			direction=0;
		}
	}
	if(k&KEY_RIGHT1){
		direction--;
		if(direction==-1){
			direction=7199;
		}
	}
	if((k&KEY_DOWN1)&&!(bk&KEY_DOWN1)){
		range-=2;
		if(range==8){
			range=10;
		}
	}
	if((k&KEY_UP1)&&!(bk&KEY_UP1)){
		range+=2;
		if(range==62){
			range=60;
		}
	}

sprite_set_location(10,	(tama[0].x+cos[direction/20]*range)/ACCURACY+-3,
						(tama[0].y+sin[direction/20]*range)/ACCURACY-3);


power++;
if(power>1024){
	power=0;
}

power_show(power/16);

sprite_set_location(0,tama[0].x/ACCURACY-4,tama[0].y/ACCURACY-4);

}

sprite_set_range(0,10);
tama[0].dx=cos[direction/20]*power/ACCURACY;
tama[0].dy=sin[direction/20]*power/ACCURACY;

/************************************************
玉射出ルーチン
*************************************************/

loop=1;
count=COUNTMAX;
k=0xFFFF;

while(loop){

/*球移動・減速*/

for(i=0;i<10;i++){
	tama[i].x+=tama[i].dx;
	tama[i].y+=tama[i].dy;

/*バウンド判定。*/

if( ( tama[i].y>14*ACCURACY) && (tama[i].y<(14*8+1)*ACCURACY)){
	if( (tama[i].x>(27*8-3)*ACCURACY) && (tama[i].dx>0) ){tama[i].dx*=-1;}
	if( (tama[i].x<ACCURACY*(8+3)) && (tama[i].dx<0) ){tama[i].dx*=-1;}
}
if( ( ( (tama[i].x>14*ACCURACY) && (tama[i].x<(13*8+1)*ACCURACY) )) ||
      ( (tama[i].x>(15*8-1)*ACCURACY) && (tama[i].x<(26*8+1)*ACCURACY) ) )   {
	if( (tama[i].y<ACCURACY*(8+3)) && (tama[i].dy<0) ){tama[i].dy*=-1;}
	if( (tama[i].y>(15*8-3)*ACCURACY) && (tama[i].dy>0) ){tama[i].dy*=-1;}
}

/*ボールポケットの判定＞まとめろ、おれ*/

if ( ( (tama[i].x-7*ACCURACY)*(tama[i].x-7*ACCURACY)+
       (tama[i].y-7*ACCURACY)*(tama[i].y-7*ACCURACY) ) <64*ACCURACY*ACCURACY){
			se_play_n(3);
	tama[i].flag|=1;
}

if ( ( (tama[i].x-217*ACCURACY)*(tama[i].x-217*ACCURACY)+
       (tama[i].y-7*ACCURACY)*(tama[i].y-7*ACCURACY) ) <64*ACCURACY*ACCURACY){
			se_play_n(3);
	tama[i].flag|=1;
}

if ( ( (tama[i].x-7*ACCURACY)*(tama[i].x-7*ACCURACY)+
       (tama[i].y-121*ACCURACY)*(tama[i].y-121*ACCURACY) ) <64*ACCURACY*ACCURACY){
	tama[i].flag|=1;
			se_play_n(3);
}

if ( ( (tama[i].x-217*ACCURACY)*(tama[i].x-217*ACCURACY)+
       (tama[i].y-121*ACCURACY)*(tama[i].y-121*ACCURACY) ) <64*ACCURACY*ACCURACY){
	tama[i].flag|=1;
			se_play_n(3);
}

if ( ( (tama[i].x-112*ACCURACY)*(tama[i].x-112*ACCURACY)+
       (tama[i].y)*(tama[i].y) ) <64*ACCURACY*ACCURACY){
	tama[i].flag|=1;
			se_play_n(3);
}

if ( ( (tama[i].x-112*ACCURACY)*(tama[i].x-112*ACCURACY)+
       (tama[i].y-128*ACCURACY)*(tama[i].y-128*ACCURACY) ) <64*ACCURACY*ACCURACY){
	tama[i].flag|=1;
			se_play_n(3);
}

if(tama[i].flag&1){
	tama[i].x=0;
	tama[i].y=20*8*ACCURACY;
	tama[i].dx=0;
	tama[i].dy=0;

screen_fill_char(SCREEN1,18+i,16,1,1,i+17);
}
	
sprite_set_location(i,tama[i].x/ACCURACY-4,tama[i].y/ACCURACY-4);

/* 減速はCOUNTMAXフレームごとに80%に減速。*/

	if(count==0){
		if( (tama[i].dx>0) || (tama[i].dx<0)){
			tama[i].dx*=8;
			tama[i].dx/=10;
		}
		if( (tama[i].dy>0) || (tama[i].dy<0)){
			tama[i].dy*=8;
			tama[i].dy/=10;
		}
	}

}

if(count==0){
	count=COUNTMAX+1;
}
count--;

/************************************************
衝突判定
*************************************************/

for(ba=0;ba<9;ba++){
	for(bb=ba+1;bb<10;bb++){
		if (( (((tama[ba].x-tama[bb].x))*((tama[ba].x-tama[bb].x))+
		     ((tama[ba].y-tama[bb].y))*((tama[ba].y-tama[bb].y)))<6*6*ACCURACY*ACCURACY )
		     && ((tama[ba].flag &1) == 0 ) && ((tama[bb].flag&1) == 0) ){

			if(ba==0 && first_hit==0){
				first_hit=bb;
			}

		if( (tama[ba].flag & (1<<bb) ) ==0 ){
			tama[ba].flag |= (1<<bb);
			se_play_n(1);

			ddx=(tama[bb].x-tama[ba].x);
			ddy=(tama[bb].y-tama[ba].y);

			hit_tama[ba].dx=(tama[ba].dx*ddx+tama[ba].dy*ddy);
			hit_tama[ba].dy=(-tama[ba].dx*ddy+tama[ba].dy*ddx);

			hit_tama[bb].dx=(tama[bb].dx*ddx+tama[bb].dy*ddy);
			hit_tama[bb].dy=(-tama[bb].dx*ddy+tama[bb].dy*ddx);

			tama[ba].dx=(hit_tama[bb].dx*ddx-hit_tama[ba].dy*ddy)/(ddx*ddx+ddy*ddy);
			tama[ba].dy=(hit_tama[bb].dx*ddy+hit_tama[ba].dy*ddx)/(ddx*ddx+ddy*ddy);

			tama[bb].dx=(hit_tama[ba].dx*ddx-hit_tama[bb].dy*ddy)/(ddx*ddx+ddy*ddy);
			tama[bb].dy=(hit_tama[ba].dx*ddy+hit_tama[bb].dy*ddx)/(ddx*ddx+ddy*ddy);
		}
		} else {
			tama[ba].flag &= ( (1<<bb)^65535);
		}
	}
}


/************************************************
キー判定
************************************************/

bk=k;
k=key_press_check();


if(k&KEY_START){
	loop=0;
	mainloop=0;
}

	if((k&KEY_B)&&!(bk&KEY_B)){
		for(i=1;i<10;i++){
			sprite_set_char(i,i+38);
		}
	}
	if(!(k&KEY_B)&&(bk&KEY_B)){
		for(i=1;i<10;i++){
			sprite_set_char(i,i+17);
		}
	}

/*デバッグ用

if((k&KEY_A)&&!(bk&KEY_A)){
	tama[0].dx*=2;
	tama[0].dy*=2;
}
if((k&KEY_B)&&!(bk&KEY_B)){
	tama[0].dx/=2;
	tama[0].dy/=2;
}

if((k&KEY_UP2)&&!(bk&KEY_UP2)){
bs_set_target(KH_BS_SCREEN1 | KH_BS_SPRITE);
bs_sprite_set_range(0, 10);
bsc_save_screen_xmodem("biloke", 0, 0, 224, 144);
}
*/


/************************************************
停止判定
*************************************************/

bb=0;
for(ba=0;ba<10;ba++){
	if(tama[ba].dx==0 && tama[ba].dy==0){
		bb++;
	}
}
if(bb==10){
	loop=0;
}



sys_wait(1);



}

/************************************************
終了処理
*************************************************/

shot_num++;
if(tama[0].flag&1){
	mainloop=0;
}

}

/* ゲームオーバー表示 */

	for(i=1;i<7;i++){
		sprite_set_char(i+9,i+47);
		sprite_set_location(i+9,80+i*8,72);
	}
sprite_set_range(0,16);

se_play_n(4);

key_wait();

}

/************************************************
絶対値関数
*************************************************/

long int abs(long int i){
	if(i<0){
		i*=-1;
	}
return i;
}


/************************************************
パワーゲージ表示関数
*************************************************/

void power_show(signed int power){
	int x=0;
	
	while(power>0){
		if(power>8){
			screen_fill_char(SCREEN1,x,16,1,1,8);
		} else {
			screen_fill_char(SCREEN1,x,16,1,1,power);
		}
		power-=8;
		x++;
	}
	
	if(x<8){
		screen_fill_char(SCREEN1,x,16,(8-x),1,0);
	}
}






