/*
*	Yamana's Otomeza Plug-in Tool
*		色変更ポリゴン
*	
*	1995.08.13	
*	1995.08.18	タイルパターンへの変更を可能にした
*	1995.08.24	色の置換を可能にした
*	
*/
#include	"otome_pi.h"

const char longname[] = "DRAW  : カラーチェンジ";
int			cnfg_max = 1;
PI_CNFG		cnfg[] =
			{	/* 1234567890123456 ,min,max,def,set */
				{ "相互置換 →する"	,  0,  1,  0,  0 },
			};

#define	USE_TYPE	PI_DRAW_POLY
#define	USE_ENV		PI_SET_ENV
#include	"otome_pi.c"

/*******************************************************/
/* ポリゴンの最大矩形座標を求める */
void get_rectangle( fr )
FRAME	*fr;
{
	unsigned int 	minx,miny,maxx,maxy;
	int 	i,x,y;
	
	minx = miny = (-1);
	maxx = maxy = 0;
	for( i=0; i< WORD( g_para ) ; i++ )
	{	x = WORD( g_para+2+i*4 );
		y = WORD( g_para+4+i*4 );
		if( x<minx )	minx = x;
		if( x>maxx )	maxx = x;
		if( y<miny )	miny = y;
		if( y>maxy )	maxy = y;
	}
	fr->lupx = minx;	fr->lupy = miny;
	fr->rdwx = maxx;	fr->rdwy = maxy;
	
}

/*****************************/

char Bit[]		= { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };

/* 描画可能のとき !0 を返す */

#define		getMaskBit( _x, _y )	\
		(pi_imge->edit[((_x)>>3) + (_y)*(pi_imge->size.x>>3) ]	\
					& Bit[ (_x) & 7] )
#define		setMaskBit( _x, _y )	\
		(pi_imge->edit[((_x)>>3) + (_y)*(pi_imge->size.x>>3) ]	\
					&= (Bit[ (_x) & 7] ^ 0xff) )


void	setmask16( fr, col )
FRAME	*fr;
int 	col;
{
	int 	x,y,ypos,pos;
	
	for( y=fr->lupy; y<=fr->rdwy; y++ )
	{	ypos = y*(pi_imge->size.x>>3);
		
		for( x=fr->lupx; x<=fr->rdwx; x++ )
		{	
			pos = (x>>3) + ypos;
			if( pi_imge->edit[ pos ] == 0 )	/* 範囲外であるなら飛ばす */
			{	x += (7-(x & 7));
				continue;
			}
			if( (pi_imge->edit[ pos ] & Bit[x & 7])==0 )
				continue;
			
			if( ((pi_imge->image[(x>>1) + y*(pi_imge->size.x>>1)]
					>>((x&1)? 4:0 )) & 0x0f)  != col )
				pi_imge->edit[ pos ] &= (Bit[x & 7]^0xff);
			
		}
	}
}

void	setmask256( fr, col )
FRAME	*fr;
int 	col;
{
	int 	x,y,ypos,pos;
	
	for( y=fr->lupy; y<=fr->rdwy; y++ )
	{	ypos = y*(pi_imge->size.x>>3);
		
		for( x=fr->lupx; x<=fr->rdwx; x++ )
		{	
			pos = (x>>3) + ypos;
			if( pi_imge->edit[ pos ] == 0 )	/* 範囲外であるなら飛ばす */
			{	x += (7-(x & 7));
				continue;
			}
			if( (pi_imge->edit[ pos ] & Bit[x & 7])==0 )
				continue;
			
			if( pi_imge->image[ x + y * pi_imge->size.x ] != col )
				pi_imge->edit[ pos ] &= (Bit[x & 7]^0xff);
			
		}
	}
}

void	setmask32K( fr,col )
FRAME	*fr;
int 	col;
{
	int 	x,y,ypos,pos;
	
	for( y=fr->lupy; y<=fr->rdwy; y++ )
	{	ypos = y*(pi_imge->size.x>>3);
		
		for( x=fr->lupx; x<=fr->rdwx; x++ )
		{	
			pos = (x>>3) + ypos;
			if( pi_imge->edit[ pos ] == 0 )	/* 範囲外であるなら飛ばす */
			{	x += (7-(x & 7));
				continue;
			}
			if( (pi_imge->edit[ pos ] & Bit[x & 7])==0 )
				continue;
			
			if( WORD( pi_imge->image +((x+y*pi_imge->size.x)<<1)) != col )
				pi_imge->edit[ pos ] &= (Bit[x & 7]^0xff);
			
		}
	}
	
}

/**********************************************************************/
void	colchg_16( fr,c0,c1 )
FRAME	*fr;
int 	c0,c1;
{
	int 	x,y,ypos,pos;
	char	*p;
	
	for( y=fr->lupy; y<=fr->rdwy; y++ )
	{	ypos = y*(pi_imge->size.x>>3);
		
		for( x=fr->lupx; x<=fr->rdwx; x++ )
		{	
			pos = (x>>3) + ypos;
			if( pi_imge->edit[ pos ] == 0 )	/* 範囲外であるなら飛ばす */
			{	x += (7-(x & 7));
				continue;
			}
			if( (pi_imge->edit[ pos ] & Bit[x & 7])==0 )
				continue;
			
			p = &pi_imge->image[(x>>1) + y*(pi_imge->size.x>>1)];
			if( x & 1 )
			{		 if(((*p>>4)&0x0f)== c0 )	*p = (*p & 0x0f) | (c1<<4);
				else if(((*p>>4)&0x0f)== c1 )	*p = (*p & 0x0f) | (c0<<4);
			}else
			{		 if( (*p & 0x0f)== c0 )		*p = (*p & 0xf0) | c1 ;
				else if( (*p & 0x0f)== c1 )		*p = (*p & 0xf0) | c0 ;
			}
		}
	}
}

void	colchg_256( fr,c0,c1 )
FRAME	*fr;
int 	c0,c1;
{
	int 	x,y,ypos,pos;
	char	*p;
	
	for( y=fr->lupy; y<=fr->rdwy; y++ )
	{	ypos = y*(pi_imge->size.x>>3);
		
		for( x=fr->lupx; x<=fr->rdwx; x++ )
		{	
			pos = (x>>3) + ypos;
			if( pi_imge->edit[ pos ] == 0 )	/* 範囲外であるなら飛ばす */
			{	x += (7-(x & 7));
				continue;
			}
			if( (pi_imge->edit[ pos ] & Bit[x & 7])==0 )
				continue;
			
			p = &pi_imge->image[ x + y*pi_imge->size.x ];
			
				 if( *p == c0 )	*p = c1;
			else if( *p == c1 )	*p = c0;
		}
	}
}

void	colchg_32K( fr,c0,c1 )
FRAME	*fr;
int 	c0,c1;
{
	int 	x,y,ypos,pos;
	char	*p;
	
	for( y=fr->lupy; y<=fr->rdwy; y++ )
	{	ypos = y*(pi_imge->size.x>>3);
		
		for( x=fr->lupx; x<=fr->rdwx; x++ )
		{	
			pos = (x>>3) + ypos;
			if( pi_imge->edit[ pos ] == 0 )	/* 範囲外であるなら飛ばす */
			{	x += (7-(x & 7));
				continue;
			}
			if( (pi_imge->edit[ pos ] & Bit[x & 7])==0 )
				continue;
			
			p = &pi_imge->image[ (x+y*pi_imge->size.x)<<1 ];
			
				 if( WORD(p) == c0 )	WORD(p) = (short)c1;
			else if( WORD(p) == c1 )	WORD(p) = (short)c0;
		}
	}
	
}

/**********************************************************************/

int APL_exec()
{
	FRAME	fr;
	int 	mode;
	
	mode = cnfg[0].val;
	
	/* 矩形範囲を得る */
	get_rectangle( &fr );
	
	if( mode )
	{	if( PI_TILEFLG )	return ERROR;
		
		if( pi_imge->pix <8 )	colchg_16 ( &fr, PI_BACKCOL,PI_FORECOL );
		if( pi_imge->pix==8 )	colchg_256( &fr, PI_BACKCOL,PI_FORECOL );
		if( pi_imge->pix >8 )	colchg_32K( &fr, PI_BACKCOL,PI_FORECOL );
		
		return NOERR;
	}
	/* マスク設定 */
		 if( pi_imge->pix  < 8 )	setmask16 ( &fr, PI_BACKCOL );
	else if( pi_imge->pix == 8 )	setmask256( &fr, PI_BACKCOL );
	else if( pi_imge->pix  > 8 )	setmask32K( &fr, PI_BACKCOL );
	
	
	EGB_writePage( EgbPtr, PI_PAGE );
	EGB_mask	 ( EgbPtr, EGB_MASK_ON );
	
	if( PI_TILEFLG )
	{	EGB_tilePattern( EgbPtr, EGB_PAINTCOL,
					PI_TILE_X, PI_TILE_Y, PI_TILE_PAT );
		EGB_paintMode( EgbPtr, EGB_PAINT_TILEF );
	}else
	{	EGB_color( EgbPtr, EGB_PAINTCOL,  PI_FORECOL );
		EGB_paintMode( EgbPtr, EGB_PAINT_BETAFF );
	}
	
	EGB_rectangle( EgbPtr, &fr );
	
	return NOERR;
}

