/*
*	Yamana's Otomeza Plug-in Tool
*		熊手
*	
*	1995.07.23	熊手ペンの余分な処理を削除した
*	1995.07.30	75% ほど高速化, size=2^n のとき乱数に偏りが出るのを改善
*	1995.08.06	マスク部分の動作を設定できるようにした
*	
*/
#include	"otome_pi.h"

const char longname[] = "EFFECT: 熊手";
int			cnfg_max = 3;
PI_CNFG		cnfg[] = {
				{"熊手の数"			, 1, 16,  4,  4 },
				{"熊手の大きさ"		, 2, 32,  8,  8 },
				{"マスク→散らない"	, 0,  1,  0,  0 },
			};

#define	USE_ENV		PI_SET_ENV
#define	USE_TYPE	PI_DRAW_BOXF
#define	USE_PEN		PI_USER_PEN
#include	"otome_pi.c"

/*******************************************************/

int Bit[] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };

/* 描画可能のとき !0 を返す */
#if 0
int 	getMaskBit( _x, _y)
int 	_x,_y;
{
	return (pi_imge->edit[((_x)>>3) + (_y)*(pi_imge->size.x>>3) ]
					& Bit[ (_x) & 7] );
}
#else

#define		getMaskBit( _x, _y )	\
		(pi_imge->edit[((_x)>>3) + (_y)*(pi_imge->size.x>>3) ]	\
					& Bit[ (_x) & 7] )

#endif

void	chgFunc16( x1,y1,x2,y2 ,mode)
int 	x1,y1,x2,y2,mode;
{
	int col1 = (pi_imge->image[ (x1>>1) + y1*(pi_imge->size.x>>1) ]
					>>((x1 & 1)? 4:0))& 0x0f ;
	int col2 = (pi_imge->image[ (x2>>1) + y2*(pi_imge->size.x>>1) ]
					>>((x2 & 1)? 4:0))& 0x0f ;
	char	*p;
	
	if( mode == 0 )
	{
		if( getMaskBit(x2,y2) )
		{	p = &( pi_imge->image[ (x2>>1) + y2*(pi_imge->size.x>>1)] );
			
			if( x2 & 1 )	*p = (*p & 0x0f) | ((col1<<4)& 0xf0);
					else	*p = (*p & 0xf0) | ((col1   )& 0x0f);
		}
		if( getMaskBit(x1,y1) )
		{	p = &( pi_imge->image[ (x1>>1) + y1*(pi_imge->size.x>>1)] );
		
			if( x1 & 1 )	*p = (*p & 0x0f) | ((col2<<4)& 0xf0);
					else	*p = (*p & 0xf0) | ((col2   )& 0x0f);
		}
	}
	else	/* 共にマスク外 */
	{	if( getMaskBit(x1,y1) && getMaskBit(x2,y2) )
		{	p = &( pi_imge->image[ (x2>>1) + y2*(pi_imge->size.x>>1)] );
			
			if( x2 & 1 )	*p = (*p & 0x0f) | ((col1<<4)& 0xf0);
					else	*p = (*p & 0xf0) | ((col1   )& 0x0f);
			
			p = &( pi_imge->image[ (x1>>1) + y1*(pi_imge->size.x>>1)] );
			
			if( x1 & 1 )	*p = (*p & 0x0f) | ((col2<<4)& 0xf0);
					else	*p = (*p & 0xf0) | ((col2   )& 0x0f);
		}
	}
}

void	chgFunc256( x1,y1,x2,y2 ,mode)
int 	x1,y1,x2,y2,mode;
{
	int 	col1 = (pi_imge->image[ x1 + y1*(pi_imge->size.x) ])& 0xff ;
	int 	col2 = (pi_imge->image[ x2 + y2*(pi_imge->size.x) ])& 0xff ;
	
	if( mode==0 )
	{	
		if( getMaskBit(x2,y2) )
			pi_imge->image[ x2 + y2*(pi_imge->size.x) ] = col1;
		if( getMaskBit(x1,y1) )
			pi_imge->image[ x1 + y1*(pi_imge->size.x) ] = col2;
	}
	else
	{	if( getMaskBit(x1,y1) && getMaskBit(x2,y2) )
		{	pi_imge->image[ x2 + y2*(pi_imge->size.x) ] = col1;
			pi_imge->image[ x1 + y1*(pi_imge->size.x) ] = col2;
		}
	}
}

void	chgFunc32K( x1,y1,x2,y2 ,mode)
int 	x1,y1,x2,y2,mode;
{
	char	*p1 = &( pi_imge->image[(x1<<1) + y1*(pi_imge->size.x<<1)] );
	char	*p2 = &( pi_imge->image[(x2<<1) + y2*(pi_imge->size.x<<1)] );
	char	tmp[2];
	
	tmp[0] = *p2,	tmp[1] = *(p2+1);
	
	if( mode==0 )
	{	if( getMaskBit(x2,y2) )
			*p2 = *p1,		*(p2+1) = *(p1+1);
		if( getMaskBit(x1,y1) )
			*p1 = tmp[0],	*(p1+1) = tmp[1];
	}else
	{	if( getMaskBit(x1,y1) && getMaskBit(x2,y2) )
		{	*p2 = *p1,		*(p2+1) = *(p1+1);
			*p1 = tmp[0],	*(p1+1) = tmp[1];
		}
	}
}
/**********************************************************************/

int APL_exec()
{
	int 	i,j,k;
	int 	ch,mx,my;
	int 	val,size,mode;
	
	register int	x,y;
	int 	x1,y1,x2,y2,xs,ys,dx,dy;
	void	(*chgFunc)();
	FRAME	fr;
	
#ifdef DEBUG
	clock_t	t;
	t = clock();
#endif
	
	val  = cnfg[0].val * 2;
	size = cnfg[1].val;
	mode = cnfg[2].val;
	
	fr.lupx = WORD( g_para + 0 );
	fr.lupy = WORD( g_para + 2 );
	fr.rdwx = WORD( g_para + 4 );
	fr.rdwy = WORD( g_para + 6 );
	
	if( pi_imge->pix  < 8 )	chgFunc = chgFunc16;
	if( pi_imge->pix == 8 )	chgFunc = chgFunc256;
	if( pi_imge->pix  > 8 )	chgFunc = chgFunc32K;
	
	srand( (unsigned int)clock() );
	for( k=fr.lupy; k<fr.rdwy; k+=size )
	{
		y = k ;
		ys= size;
		if( (dy=(y + ys - fr.rdwy)) > 0 )	ys -= dy;
		
		for( j=fr.lupx; j<fr.rdwx; j+=(size>>1) )
		{
			MOS_rdpos( &ch, &mx, &my );
			if( ch & MOS_RIGHT )
				break;
			
			x = j ;
			xs= size;
			if( (dx=(x + xs - fr.rdwx)) > 0 )	xs -= dx;
			
			for( i=0; i<val ; i++ )
			{
				x1 = x + (rand() % (xs+1));
				x2 = x + (rand() % (xs  ));
				y1 = y + (rand() % (ys+1));
				y2 = y + (rand() % (ys  ));
				
				chgFunc( x1,y1,x2,y2 ,mode);
				
			}
		}
	}
	
	do
	{	MOS_rdpos( &ch, &mx, &my );
	}while( ch & MOS_RIGHT );
	
	
#ifdef DEBUG
	printf("clock = %d", clock()-t );
#endif
	
	memcpy( ret_fr, &fr, sizeof(fr) );
	
	return NOERR;
}

/*
	速度比較
	
	val=4,size=8
	
		EGB_point	使用しない	!EGB_pset		マスク		マクロ使用
	
	16		980			785			232			272			257/269
	256		965			758			204			249			230/245
	32k		653			530			130			161			151/160
	
	互換モード
	530/602
	
*/
