/*****************************************************************

			Ｇ-Ｐｅｎ１６	〔試作版〕	ver.0.720
							Copyright(C) 1991-1994 OKOME
*****************************************************************/

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<math.h>
#include	<fmcfrb.h>
#include	<EGB.H>
#include	<MOS.H>
#include	<kkstr2.h>
#include	<normlib.h>
#include	<okome.h>
#define	MAIN
#include	<GPen16.h>
#undef	MAIN

void endu(void)
{
	if(message2(1, "Ｇ-Ｐｅｎ１６を終了します", 2)==0)
		end();
}

void draw()		/*	画面初期化	*/
{
	int i, x, y;
	char c[64] = { 0x3210, 0x7654, 0xBA98, 0xFEDC };
	char *tl[] = {"〜","／","□","■","○","●","楕○","楕●","↑↓","←→",
				"Poly","塗","Copy","Roll","ぼけ","回転","拡縮","反転",
				"⇔","⇔重","〜","Roll","色々","もわ" };
	wpg(0);
	EGB_tmenuPalette2( work );
	MEN_sidein(2);		/*	メニューへのサイドワークの追加	*/
	MEN_set(2);
	font12( 592, 16, "大", 15 );
	font12( 615, 16, "終", 15 );
	boxf( 0, 20, 639, 479, BCL );
	KAN_disp(KAN_DISPON);
	KAN_setMode(0x30140);
	wpg(1);
	EGB_displayStart( work, 2, bi, bi );
	EGB_displayStart( work, 3, 640/bi, 480/bi );
	egbputZ( CSX1, CSY1, CSX2, CSY2, 16, 1, c );
	for ( y = 0; y < 2; y++ ) {
		for ( i = 0; i < 8; i++ ) {
			boxf( PALX +  i   *PALB  , PALY +  y   *PALB  ,
				  PALX + (i+1)*PALB-1, PALY + (y+1)*PALB-1, y*8+i );
		}
	}
	boxf( PCX1, PCY1, PCX2, PCY2, mcl[0] );
	mbclp();
	wpg(0);
	biboxbf( WX1, WY1, WX2, WY2, 0, 8, 8 );
	biboxbf( BX1, BY1, BX2, BY2, 0, 8, 8 );
	biboxbf( NX1, NY1, NX2, NY2, 0, 4, 4 );
/*	biboxbf( CBX1, CBY1, CBX2, CBY2, 0, 4, 4 );
	biboxbf( CBLX1, CBLY1, CBLX2, CBLY2, 0, 2, 2 );
	biboxbf( CBRX1, CBRY1, CBRX2, CBRY2, 0, 2, 2 );
*/	for ( i = 0; i < MEZ0; i++ ) {
		x = i % MEX2;
		y = i / MEX2;
		uboxf( MEX1+MEX4*x, MEY1+MEY4*y,
			  MEX1+MEX4*(x+1)-1, MEY1+MEY4*(y+1)-1, 15, 8, (i<MEZ1) ? 7 : 12 );
		symbol(MEX1+MEX4*x+MEX4/2-strlen(tl[i])*4,MEY1+MEY4*y+18,
			   tl[i], 16, 15 );
	}
	wkugiri(1);
	biboxbf( PALX, PALY, PALX+127, PALY+PALB*3-1, 0, 4, 28 );
	biboxbf( PCX1, PCY1, PCX2, PCY2, 0, 0, 0 );
	biboxbf( PLX1, PLY1, PLX2, PLY2, 0, 0, 0 );
	biboxbf( PRX1, PRY1, PRX2, PRY2, 0, 0, 0 );
	ubox( SPX1, SPY1, SPX2, SPY2, 15, 8 );
	font12( SPX1+6, SPY2-4, "SPOIT", 15 );
	ubox( PAX1, PAY1, PAX2, PAY2, 8, 15 );
	ubox( HX1, HY1, HX2, HY2, 8, 15 );
	bfgs(1);
	for (y=0; y<=2; y++)
		mcolms(y);
	wpg(1);
	page(0);
}

void gmenu( int mx, int my )		/*	アイコンMENU	*/
{
	int x, y, i, j;
	
	i = (( mx - MEX1 ) / MEX4) + MEX2 * (( my - MEY1 ) / MEY4);
	j = ( i<MEZ1 ) ? 0 : 1 ;
	x = MEX1 +((mei[j] + j * MEZ1) % MEX2)* MEX4;
	y = MEY1 + (mei[j] + j * MEZ1) / MEX2 * MEY4;
	mei[j] = i - j * MEZ1;
	mx = MEX1 +(i % MEX2)* MEX4;
	my = MEY1 + i / MEX2 * MEY4;
	wpg(0);
	ubox(  x,  y,  x+MEX4-1,  y+MEY4-1, 15, 8 );
	ubox( mx, my, mx+MEX4-1, my+MEY4-1, 8, 15 );
	wpg(1);
}

void mcolm( int mb, int mx, int my )		/*	カラー選択バー	*/
{
	int i, j, c;
	j = ( my - PALY*bi ) / ( PALB*bi );
	i = ( 1 << ((2 - j) * 5) );
	umosv(PALX, PALY+PALB*j, PALX+127, PALY+PALB*(j+1)-1 );
	while (mb!=0)
	{
		MOS_rdpos( &mb, &mx, &my );
		c = (mx - PALX*bi) / 8;
		mcols((mcl[0] & (0xffff - 0x1f * i)) + c * i);
	}
	mosv(0, 0, 639, 479);
}

void rollsub( int x3, int y3, int X1, int Y1, int X3, int Y3 )
{
	int X2, Y2, Y4;
	X2 = X1+X3;
	Y2 = Y1+Y3;
	Y4 = Y3+1;
	egbget( X1, Y1, X1+(x3-1 & X3), Y2, b );
	egbget( X1+x3, Y1, X2, Y2, &(b[x3*Y4*2]) );
	egbput( X2-(x3-1 & X3), Y2-(y3-1 & Y3), X2, Y2, b );
	egbput( X2-(x3-1 & X3), Y1, X2, Y2-y3, &(b[x3*y3*2]) );
	egbput( X1, Y2-(y3-1 & Y3), X2-x3, Y2, &(b[x3*Y4*2]) );
	egbput( X1, Y1, X2-x3, Y2-y3, &(b[(x3*Y4+(X3-x3+1)*y3)*2]) );
}

void rollsander( int mb, int mx, int my )
{
	int x2, y2, x3, y3;
	mx = wnx(mx);
	my = wny(my);
	do
	{
		MOS_rdpos( &mb, &x2, &y2 );
		x3 = mx - wnx(x2) & NX3;
		y3 = my - wny(y2) & NY3;
		rollsub( x3, y3, NX1, NY1, NX3, NY3 );
		wkk();
		mx = wnx(x2);
		my = wny(y2);
	}	while (mb);
}

/*	編集窓用機能軍	*/

void mpaint( int mb, int mx, int my )
{
	char pa[4];
	EGB_paintMode( work, 0x22 );
	EGB_color( work, 2, mcl[mb] );
	WORD(pa) = wnx(mx);
	WORD(pa+2) = wny(my);
	EGB_closePaint( work, pa );
	wkk();
}

void mdr( int mb, int mx, int my )	/*	編集窓描画	*/
{
	int mx2, my2, x, y, x2, y2;
	mx2 = mx;
	my2 = my;
	while (mb != 0 && mx/bi >= WX1 && mx/bi <= WX2 &&
					  my/bi >= WY1 && my/bi <= WY2 )
	{
		line( wnx(mx2), wny(my2), wnx(mx), wny(my), mcl[mb] );
		x = wnx(mx);
		x2 = wnx(mx2);
		bsz( &x, &x2 );
		y = wny(my);
		y2 = wny(my2);
		bsz( &y, &y2 );
		egbget( x, y, x2, y2, b );
		egbputZ( WX1+(x-NX1)*KS, WY1+(y-NY1)*KS,
				 WX1+(x2-NX1+1)*KS-1, WY1+(y2-NY1+1)*KS-1,
				 x2-x+1, y2-y+1, b );
		mx2 = mx;
		my2 = my;
		MOS_rdpos( &mb, &mx, &my );
	}
}

void mwwp( int *mb, int *mx, int *my, int *x, int *y, void (*fp)() )
{
	int x2, y2, b2;
	view( WX1,WY1, WX2,WY2 );
	umosv( WX1,WY1, WX2,WY2 );
	EGB_writeMode( work, 4 );
	*mx = wcx(*mx);
	*my = wcy(*my);
	fp( *mx, *my, *mx, *my, 0x7fff );
	x2 = *mx;
	y2 = *my;
	do
	{
		b2 = *mb;
		MOS_rdpos( mb, x, y );
		*x = wcx(*x);
		*y = wcy(*y);
		if (*x != x2 || *y != y2 )
		{
			fp( *mx, *my, x2, y2, 0x7fff );
			fp( *mx, *my, *x, *y, 0x7fff );
		}
		x2 = *x;
		y2 = *y;
	}	while (*mb);
	*mb = b2;
}

void mline( int mb, int mx, int my, void (*vic)() )
{
	int x, y;
	mwwp( &mb, &mx, &my, &x, &y, vic );
	view( NX1,NY1, NX2,NY2 );
	mosv( 0,0, 639,479 );
	EGB_writeMode( work, 0 );
	vic( nbx(mx), nby(my), nbx(x), nby(y), mcl[mb] );
	wkk();
}

void mcpyl( int mb, int mx, int my, int c )
{
	int x, y, x2, y2, x3, y3;
	char a[64*64*2];
	mwwp( &mb, &mx,&my, &x,&y, boxb );
	bsz( &mx, &x );
	bsz( &my, &y );
	egbget( nbx(mx),nby(my), nbx(x),nby(y), a );
	mbin( &mb, &x3, &y3 );
	if (mb == 1)
	{
		if (c)
		{
			EGB_writeMode( work, 0 );
			boxf(wnx(mx),wny(my), wnx(x), wny(y), mcl[2] );
			EGB_writeMode( work, 4 );
		}
		x3 = wcx(x3);
		y3 = wcy(y3);
		mx -= x3;
		my -= y3;
		x -= x3;
		y -= y3;
		do
		{
			MOS_rdpos( &mb, &x2, &y2 );
			x2 = wcx(x2);
			y2 = wcy(y2);
			while ( x2+x > WX2 )
				x2-=KS;
			while ( y2+y > WY2 )
				y2-=KS;
			while ( x2+mx < WX1 )
				x2+=KS;
			while ( y2+my < WY1 )
				y2+=KS;
			if (x3 != x2 || y3 != y2 )
			{
				boxb( x3+mx,y3+my, x3+x,y3+y, 0x7fff );
				boxb( x2+mx,y2+my, x2+x,y2+y, 0x7fff );
			}
			x3 = x2;
			y3 = y2;
		}	while (mb);
		view( NX1,NY1, NX2,NY2 );
		EGB_writeMode( work, 0 );
		egbput( nbx(x3+mx),nby(y3+my), nbx(x3+x),nby(y3+y), a );
	}
	EGB_writeMode( work, 0 );
	mosv( 0,0, 639,479 );
	wkk();
}

void mnw( int mb, int mx, int my )		/*	編集窓	*/
{
	view( NX1, NY1, NX2, NY2 );
	switch(mei[0])
	{
	case 1:	mline( mb, mx, my, line );		break;
	case 2:	mline( mb, mx, my, boxb );		break;
	case 3:	mline( mb, mx, my, boxf );		break;
	case 4:	mline( mb, mx, my, circlen2 );	break;
	case 5:	mline( mb, mx, my, circlef2 );	break;
	case 6:	mpaint( mb, mx, my );			break;
	case 7:	rollsander( mb, mx, my );		break;
	case 8: mcpyl( mb, mx, my, 0 );			break;
	default:	mdr( mb, mx, my );			break;
	}
	view( 0, 0, 1024/bi-1, 512/bi-1 );
}

void mbwk( int mx, int my, int c )	/*	バッファセット用枠	*/
{
	static int x = 0, y = 512, c2 = 0;
	int mx2, my2;
	if ( mx/bi < BX1 || mx/bi > BX2 || my/bi < BY1 || my/bi > BY2 )
	{
		c = 0;
	}
	if ( c == 0 )
	{
		if ( c2 != 0 )
		{
			wpg(0);
			boxb( x, y, x+NX4*bi-1, y+NY4*bi-1, 0 );
			wpg(1);
		}
	}	else	{
		mx2 = gpx(mx)*bi;
		my2 = gpy(my)*bi;
		if ( x != mx2 || y != my2 || c2 == 0 )
		{
			wpg(0);
			boxb( x, y, x+NX4*bi-1, y+NY4*bi-1, 0 );
			boxb( mx2, my2, mx2+NX4*bi-1, my2+NY4*bi-1, 15 );
			wpg(1);
			x = mx2;
			y = my2;
		}
	}
	c2 = c;
}

void bfsrgp( int mb, int mx, int my )	/*	重ね合わせ	*/
{
	egbget( NX1, NY1, NX2, NY2, b );
	bfgp( mb, mx, my );
	if (mb == 2)
	{
		EGB_writeMode( work, 6 );
		EGB_color( work, 3, mcl[2] );
		egbput( NX1, NY1, NX2, NY2, b );
		EGB_writeMode( work, 0 );
		wkk();
		mbout( &mb, &mx, &my );
	}
}

void bfdraw( int mb, int mx, int my )
{
	int mx2, my2;
	mx2 = mx;
	my2 = my;
	while (mb != 0)	{
		if (mx2/bi >= BX1 && mx2/bi <= BX2 &&
		    my2/bi >= BY1 && my2/bi <= BY2 )	{
			line( mx2/bi, my2/bi, mx/bi, my/bi, mcl[mb] );
		}	else	{
			break;
		}
		mx2 = mx;
		my2 = my;
		MOS_rdpos( &mb, &mx, &my );
	}
}

void brolls( int mb, int mx, int my )
{
	int x2, y2, x3, y3;
	mx= mx/bi;
	my = my/bi;
	do
	{
		MOS_rdpos( &mb, &x2, &y2 );
		x3 = mx - x2/bi & BX3;
		y3 = my - y2/bi & BY3;
		rollsub( x3, y3, BX1, BY1, BX3, BY3 );
		mx = x2/bi;
		my = y2/bi;
	}	while (mb);
}

void mbuff( int mb, int mx, int my )		/*	バッファ	*/
{
	view( BX1, BY1, BX2, BY2 );
	switch (mei[1])
	{
	case 1:		bfsrgp( mb, mx, my );	break;
	case 2:		bfdraw( mb, mx, my );	break;
	case 3:		brolls( mb, mx, my );	break;
	default:	bfgp( mb, mx, my );		break;
	}
	view( 0, 0, 1024/bi-1, 512/bi-1 );
}

void mosmen(int mb, int mx, int my)
{
	static char nn[FILENAME_MAX];

	switch(MEN_menu( mb, mx, my ))
	{
	case 1:
		message2(4, "Ｇ-Ｐｅｎ１６    ver.0.720", "",
				    __DATE__" "__TIME__" Compiled.",
				    "Copyright(C) 1991-1994 OKOME", 1);
		break;
	case 101:
		if (OKM_fsel( nn, "TIFFload", 0 ) == 0) {
			EGB_color(work, 0, mcl[1]);
			tiffload(nn, BX1, BY1);
		}
		break;
	case 102:
		if (OKM_fsel( nn, "TIFFsave", 0 ) == 0)
			if (sachk(nn) == 0)
				tiffsave(nn, BX1, BY1, BX2, BY2, 0, 0);
		break;
	case 103:
		if (OKM_fsel( nn, "SPRITEload",0 ) == 0)
			sprload( nn, BX1, BY1 );
		break;
	case 104:
		if (OKM_fsel( nn, "SPRITEsave",0 ) == 0)
			sprsave( nn, BX1, BY1 );
		break;
	case 301:
		udten( NX1, NY1, NX2, NY2 );
		wkk();
		break;
	case 302:
		lrten( NX1, NY1, NX2, NY2 );
		wkk();
		break;
	case 303:
		wpg(0);
		wkugiri(3);
		wpg(1);
		break;
	case 304:
		wpg(0);
		wkugiri(2);
		wpg(1);
		break;
	case 9998:
		wsize(mb,1);
		break;
	case 9999:
		end();
		break;
	default:
		break;
	}
}


void keymod(unsigned int kb)
{
	switch(kb)
	{
	case 0x8016:
	case 0x9:	page(-1);	break;
	case 0x8017:
	case 0x1b:	page( 1);	break;
	default:
		if (strchr(MEN_skey,kb-'a'+'A')!=NULL)
			MEN_sideexec(strchr(MEN_skey,kb-'a'+'A')-MEN_skey+1);
		break;
	}
}

void mouse()		/*	マウス総合領域	*/
{
	int mb, mx, my, mx2, my2;
	unsigned int kb, en;
	while(1)
	{
		MOS_rdpos( &mb, &mx, &my );
		mx2 = mx / bi;
		my2 = my / bi;
		mbwk( mx, my, ( mei[1] == 2 || mei[1] == 3 ) ? 0 : 1 );
		if ((kb = KYB_read(1,&en)) != 0xffff)
			keymod(kb);
		if (mb)	{
			if ( mx2 >= WX1 && mx2 <= WX2 &&
				 my2 >= WY1 && my2 <= WY2 )
				mnw( mb, mx, my );	/*	編集窓	*/
			else if ( mx2 >= BX1 && mx2 <= BX2 &&
					  my2 >= BY1 && my2 <= BY2 )
					mbuff( mb, mx, my );	/*	バッファ	*/
			else if ( my2 >= PALY && my2 < (PALY+PALB*3) &&
					  mx2 >= PALX && mx2 <  PALX + 128)
					mcolm( mb, mx, my );	/*	カラーボックス	*/
			else if ( mx >= MEX1 && my >= MEY1 && mx < MEX1 + MEX4 * MEX2 &&
				 MEZ0 > (( mx-MEX1 ) / MEX4) + MEX2 * (( my-MEY1 ) /MEY4 ))
					gmenu( mx, my );	/*	編集メニュー	*/
			else if ( mx2 >= PCX1 && mx2 <= PCX2 && 
					  my2 >= PCY1 && my2 <= PCY2 )
					mcolm2( mb );	/*	ボタンへ色セット	*/
			else if ( mx2 >= PRX1 && mx2 <= PRX2 && 
					  my2 >= PRY1 && my2 <= PRY2 )
					mcols( mcl[2-bc] );
			else if ( mx2 >= PLX1 && mx2 <= PLX2 && 
					  my2 >= PLY1 && my2 <= PLY2 )
					mcols( mcl[1+bc] );
			if ( mx >= PAX1 && mx <= PAX2 && 
				 my >= PAY1 && my <= PAY2 )
				pbtn( mb );		/*	ページ変更	*/
			if ( mx >= SPX1 && mx <= SPX2 && 
				 my >= SPY1 && my <= SPY2 )
				mspoit();
/*			if ( mx2 >= CBX1 && mx2 <= CBX2 &&
				 my2 >= CBY1 && my2 <= CBY2 )
				tclc(mb, mx, my);
			else if ( mx2 >= CBLX1 && mx2 <= CBLX2 &&
					  my2 >= CBLY1 && my2 <= CBLY2 )
				tcl(mb, 0);
			else if ( mx2 >= CBRX1 && mx2 <= CBRX2 &&
					  my2 >= CBRY1 && my2 <= CBRY2 )
				tcl(mb, 1);
*/			if ( mx2 >= NX1 && mx2 <= NX2 &&
				 my2 >= NY1 && my2 <= NY2 )
				wsize(mb, 0);
			if ( mx >= HX1 && mx <= HX2 &&
				 my >= HY1 && my <= HY2 )
				bfgs(mb);
			if ( my < 20 )	/*	MENUバー	*/
				mosmen( mb, mx, my );
		}
	}
}

_mwset_up_args()	{ return 0; }	/*	argc argvを使わない	*/

void main()
{
	int i;
	/*	初期化	*/
	EGB_init( work, EgbWorkSize );
	EGB_resolution( work, 0, GM0 );
	EGB_resolution( work, 1, GM1 );
	MOS_start( mwork, MosWorkSize );
	MOS_writePage( 0 );
	mosv( 0, 0, 639, 479 );
	MOS_typeRom2( 81, 1, 1, mpat );
	KYB_init();
	KYB_clic( 1 );
	KYB_setcode( 0x0200);
	kkinit(KAN_SCRN16, KAN_MOSON);
	NX1 = nx[3];
	NY1 = ny[3];
	NX4 = 64/bi;
	NY4 = NX4;
	wb = wallb;
	for (i=0; i<5; i++) {
		wallbl[i] = wb;
		wb+= 32<<(i*2);
	}
	wallbl[5] = &(b[256*1024-32768]);
	wb = wallbl[3];
	mcl[1] = 0xf;
	for (vz=2000; vp0 == NULL; vz--) {
		vp0 = (char *)calloc( (vz+1)*BX4*BY4*Cb/8, 1 );
	}
	vp = vp0;
	draw();		/*	画面作り	*/
	mouse();	/*	メインへ	*/
}
