/*----------------------------------------------------------------------------
	BORN 多間接
----------------------------------------------------------------------------*/

#include "soh.h"
#include "ipx.h"
#include "born.h"
#include "math.h"

BORNBUF *bo[BON_MAX_BORN];
/*----------------------------------------------------------------------------
----------------------------------------------------------------------------*/
void boInit(void)
{
	long i;
	for(i=0; i<BON_MAX_BORN; i++) {
		bo[i]=(BORNBUF*)malloc(sizeof(BORNBUF));
		bo[i]->boUsed = 0;
	}
}
void boExit(void)
{
	long i;
	for(i=0; i<BON_MAX_BORN; i++)
		free(bo[i]);
}
/*----------------------------------------------------------------------------
	作成
----------------------------------------------------------------------------*/
short boCreate(long num)
{
	long j;
	long i;
	
	j=-1;
	for(i=BON_MAX_BORN-1; i>=0; i--)
		if (bo[i]->boUsed==0) j=i;			/* 空き場所を検索				*/
	if (j==-1) return -1;
	
	bo[j]->boUsed       = 1;				/* 使用中						*/
	bo[j]->boMode       = 0;				/* モード						*/
	bo[j]->boGrp        = 0;				/* グループ番号					*/
	bo[j]->boNum        = num;				/* 関節数						*/
	
/*	sxMemSetB(bo[j]->boJoint ,0, sizeof(JOINT)*BON_MAX_JOINT);*/
	
	for(i=0; i<num; i++) {
		bo[j]->boJoint[i].color=0xffffffff;
	}
	
	return (short)j;
}
/*----------------------------------------------------------------------------
	破棄
----------------------------------------------------------------------------*/
short boFree(u_long Handle)
{
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;

	bo[Handle]->boUsed=0;					/* 終了							*/
	return 0;
}
/*----------------------------------------------------------------------------
	距離設定（絶対）
----------------------------------------------------------------------------*/
short boSetDistAbs(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].dist.now = val; break;
		case 1: bo[Handle]->boJoint[no].dist.vec = val; break;
		case 2: bo[Handle]->boJoint[no].dist.tar = val; break;
		case 3: bo[Handle]->boJoint[no].dist.cnt = val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].dist.now = val; break;
			case 1: bo[Handle]->boJoint[i].dist.vec = val; break;
			case 2: bo[Handle]->boJoint[i].dist.tar = val; break;
			case 3: bo[Handle]->boJoint[i].dist.cnt = val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	距離設定（相対）
----------------------------------------------------------------------------*/
short boSetDistRel(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].dist.now += val; break;
		case 1: bo[Handle]->boJoint[no].dist.vec += val; break;
		case 2: bo[Handle]->boJoint[no].dist.tar += val; break;
		case 3: bo[Handle]->boJoint[no].dist.cnt += val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].dist.now += val; break;
			case 1: bo[Handle]->boJoint[i].dist.vec += val; break;
			case 2: bo[Handle]->boJoint[i].dist.tar += val; break;
			case 3: bo[Handle]->boJoint[i].dist.cnt += val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	角度設定（絶対）
----------------------------------------------------------------------------*/
short boSetRollAbs(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].roll.now = val; break;
		case 1: bo[Handle]->boJoint[no].roll.vec = val; break;
		case 2: bo[Handle]->boJoint[no].roll.tar = val; break;
		case 3: bo[Handle]->boJoint[no].roll.cnt = val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].roll.now = val; break;
			case 1: bo[Handle]->boJoint[i].roll.vec = val; break;
			case 2: bo[Handle]->boJoint[i].roll.tar = val; break;
			case 3: bo[Handle]->boJoint[i].roll.cnt = val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	角度設定（相対）
----------------------------------------------------------------------------*/
short boSetRollRel(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].roll.now += val; break;
		case 1: bo[Handle]->boJoint[no].roll.vec += val; break;
		case 2: bo[Handle]->boJoint[no].roll.tar += val; break;
		case 3: bo[Handle]->boJoint[no].roll.cnt += val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].roll.now += val; break;
			case 1: bo[Handle]->boJoint[i].roll.vec += val; break;
			case 2: bo[Handle]->boJoint[i].roll.tar += val; break;
			case 3: bo[Handle]->boJoint[i].roll.cnt += val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	Ｘ座表設定（絶対）
----------------------------------------------------------------------------*/
short boSetLocalXAbs(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].local_x.now = val; break;
		case 1: bo[Handle]->boJoint[no].local_x.vec = val; break;
		case 2: bo[Handle]->boJoint[no].local_x.tar = val; break;
		case 3: bo[Handle]->boJoint[no].local_x.cnt = val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].local_x.now = val; break;
			case 1: bo[Handle]->boJoint[i].local_x.vec = val; break;
			case 2: bo[Handle]->boJoint[i].local_x.tar = val; break;
			case 3: bo[Handle]->boJoint[i].local_x.cnt = val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	Ｘ座表設定（相対）
----------------------------------------------------------------------------*/
short boSetLocalXRel(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].local_x.now += val; break;
		case 1: bo[Handle]->boJoint[no].local_x.vec += val; break;
		case 2: bo[Handle]->boJoint[no].local_x.tar += val; break;
		case 3: bo[Handle]->boJoint[no].local_x.cnt += val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].local_x.now += val; break;
			case 1: bo[Handle]->boJoint[i].local_x.vec += val; break;
			case 2: bo[Handle]->boJoint[i].local_x.tar += val; break;
			case 3: bo[Handle]->boJoint[i].local_x.cnt += val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	Ｙ座表設定（絶対）
----------------------------------------------------------------------------*/
short boSetLocalYAbs(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].local_y.now = val; break;
		case 1: bo[Handle]->boJoint[no].local_y.vec = val; break;
		case 2: bo[Handle]->boJoint[no].local_y.tar = val; break;
		case 3: bo[Handle]->boJoint[no].local_y.cnt = val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].local_y.now = val; break;
			case 1: bo[Handle]->boJoint[i].local_y.vec = val; break;
			case 2: bo[Handle]->boJoint[i].local_y.tar = val; break;
			case 3: bo[Handle]->boJoint[i].local_y.cnt = val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	Ｙ座表設定（相対）
----------------------------------------------------------------------------*/
short boSetLocalYRel(u_long Handle, long op, long no, long val)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		switch (op) {
		case 0: bo[Handle]->boJoint[no].local_y.now += val; break;
		case 1: bo[Handle]->boJoint[no].local_y.vec += val; break;
		case 2: bo[Handle]->boJoint[no].local_y.tar += val; break;
		case 3: bo[Handle]->boJoint[no].local_y.cnt += val; break;
		}
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			switch (op) {
			case 0: bo[Handle]->boJoint[i].local_y.now += val; break;
			case 1: bo[Handle]->boJoint[i].local_y.vec += val; break;
			case 2: bo[Handle]->boJoint[i].local_y.tar += val; break;
			case 3: bo[Handle]->boJoint[i].local_y.cnt += val; break;
			}
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	関節数設定
----------------------------------------------------------------------------*/
short boSetNum(u_long Handle, long num)
{
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	bo[Handle]->boNum=num;
	return 0;
}
/*----------------------------------------------------------------------------
	グループ設定
----------------------------------------------------------------------------*/
short boSetGrp(u_long Handle, long grp)
{
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	bo[Handle]->boGrp=grp;
	return 0;
}
/*----------------------------------------------------------------------------
	パターン設定
----------------------------------------------------------------------------*/
short boSetPtn(u_long Handle, long no, long ptn)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		bo[Handle]->boJoint[no].ptn = ptn;
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			bo[Handle]->boJoint[i].ptn = ptn;
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	カラー設定
----------------------------------------------------------------------------*/
short boSetColor(u_long Handle, long no, u_long col)
{
	long i;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	if (no>=0) {
		bo[Handle]->boJoint[no].color = col;
	} else {
		for(i=0; i<bo[Handle]->boNum; i++) {
			bo[Handle]->boJoint[i].color = col;
		}
	}
	return 0;
}
/*----------------------------------------------------------------------------
	描画
----------------------------------------------------------------------------*/
short boDraw(u_long Handle, OBJECT *obj)
{
	long i;
	long ox,oy,or,od;
	JOINT *J;
	SPRITE spr;
	
	if (Handle<0 || Handle>=BON_MAX_BORN) return -1;
	if (bo[Handle]->boUsed==0) return -1;
	
	ox=obj->world_x;
	oy=obj->world_y;
	or=0;
	od=0;
	for(i=0; i<bo[Handle]->boNum; i++) {
		J=&bo[Handle]->boJoint[i];

		or += J->roll.now;
		od  = J->dist.now>>8;

		J->world_x = ox + sin(or *PI/32768.f) *od/2;
		J->world_y = oy - cos(or *PI/32768.f) *od/2;
		J->world_r = or;
		J->world_d = od;
		
		ox += sin(or *PI/32768.f) * od;
		oy +=-cos(or *PI/32768.f) * od;
		
		spr.px   =J->world_x>>16;
		spr.py   =J->world_y>>16;
		spr.prio =obj->world_z+i;
		spr.zoom =0x100;
		spr.roll =or;
		spr.mate =bo[Handle]->boJoint[i].color;
		spr.grp  =bo[Handle]->boGrp;
		spr.ptn  =bo[Handle]->boJoint[i].ptn;
		spr.attr = 0x00000000;
		ixDispSprite(&spr);
	}

	obj->ex_x = ox;
	obj->ex_y = oy;
	
	return 0;
}
/*--------------------------------------------------------------------------*/
