/*		quad expand for video recordre	1990 6/8
*/

#include <stdlib.h>
#include <math.h>
#include <egb.h>
#include <mos.h>
#include "video.h"

#define C_WT 0x7fff		/* カーソル color */
#define C_B 0x3ff		/* box color */
#define C_PL 24311		/* 初期プレーン color */
#define C_FL 0x303030		/* files back color */
#define C_COLOR 15		/* Command color palette */
#define W_COLOR 8		/* Window color palette */
#define B_COLOR 7		/* Back color palette */
#define E_COLOR 10		/* ERROR color palette */
#define S1_COLOR 4		/* SCALE1 color palette */
#define S2_COLOR 12		/* SCALE2 color palette */

extern error_check( int n );
extern mouse( int para[], int xd, int yd, int mode );
extern gprint( char *dsp, int x, int y );
extern gprint2( char *dsp, int x, int y );
extern itochar( int number, int x, char *dsp );
extern windget();
extern windput();
/* extern mov_save_trim( int var[], int color ); */
extern mov_save_page( char *name, int mode, int var[] );
extern display_scale();
extern polygon1( int para[], char *bbuf );
extern polygon2( char *bbuf );
extern polygon3( char *bbuf );

quad_expand(pvar,cvar,ework,gwork,bbuf)
int pvar[];			/* page */
int cvar[][2];			/* 座標 */
char *ework, *gwork, *bbuf;
{
	int min,max,i,j,k,wt,sw,cx,cy,polysw,mode;
	int mp[3];
	int pp[5];
	int data[2];
	char dsp1[] = "<<EXPAND>>  SOURCE-RECTANGLE  START-QUADRANGLE  END-QUADRANGLE  PAGE=       EXIT";
	char dsp2[] = "REC1  REC2  EXPAND(page    )  CANCEL            POLYGON-SET  POLYGON-OFF   TRACE";

	backupget(bbuf,gwork);		/* 全画面保存 */
	polysw = pvar[4];
	if( polysw )polygon2(bbuf);
quad1:	windget();
	gprint( dsp1, 0, 463 );
	gprint( dsp2, 0, 479 );
	EGB_color(ework,0,E_COLOR);
	gprint( "REC1  REC2", 0, 479 );
	EGB_color(ework,0,C_COLOR);
	for( i = 0 ; i < 2 ; i++ )data[i] = -1;
	quad_dsp(data,pvar);
quad2:	MOS_disp(1);
	mouse( mp, 0, 0, 1 );
	sw = mp[0]; cx = mp[1]; cy = mp[2];
	if( cy < 447 )goto quad2;
	if( cy < 463 ){
		if( cx < 88 )goto quad2;
		if( cx < 232 ){			/* source 0 */
			j = 0;
			goto quad3;
		}
		if( cx < 376 ){			/* start_quad 1 */
			j = 1;
			goto quad3;
		}
		if( cx < 504 ){			/* end_quad 2 */
			j = 2;
			goto quad3;
		}
		if( cx < 584 ){			/* page */
			i = 0; min = 2; max = 999;
			goto quad7;
		}
		if( cx < 600 )goto quad2;
		if( cx < 640 ){			/* exit 3 */
			j = 3;
			goto quad3;
		}
		goto quad2;
	}
	if( cy < 480 ){
		if( cx < 40 ){			/* rec1 */
			mode = 0;
			j = 9;
			goto quad3;
		}
		if( cx < 88 ){			/* rec2 */
			mode = 1;
			j = 9;
			goto quad3;
		}
		if( cx < 148 ){			/* expand 4 */
			j = 4;
			goto quad3;
		}
		if( cx < 232 ){			/* page */
			i = 1; min = 1; max = pvar[0];
			goto quad7;
		}
		if( cx < 296 ){			/* cancel 5 */
			j = 5;
			goto quad3;
		}
		if( cx < 376 )goto quad2;
		if( cx < 480 ){			/* POLYGON-SET 6 */
			j = 6;
			goto quad3;
		}
		if( cx < 584 ){			/* POLYGON-OFF 7 */
			j = 7;
			goto quad3;
		}
		if( cx < 592 )goto quad2;
		if( cx < 640 ){			/* trace 8 */
			j = 8;
			goto quad3;
		}
		goto quad2;
	}
	goto quad2;
quad3:	mouse(mp, 0, 0, 0);
	sw = mp[0]; cx = mp[1]; cy = mp[2];
	if( sw > 1 )goto quad2;
	MOS_disp(0);
	windput();
	switch( j ){
		case 0: rectangle_coodr( cvar,ework );	/* rectangole */
			break;
		case 1:	sourcebox_display(cvar,ework);
			quad_coodr( cvar, 2, ework );	/* start quad */
			sourcebox_display(cvar,ework);
			break;
		case 2:	sourcebox_display(cvar,ework);
			quad_coodr( cvar, 6, ework );	/* end quad */
			sourcebox_display(cvar,ework);
			break;
		case 3:	polygon2( bbuf );
			return 0;			/* exit */
		case 4:	polygon2( bbuf );		/* expand */
			error_check(
				expand_copy(pvar,cvar,polysw,bbuf,ework,gwork)
			);
			polygon2( bbuf );
			break;
		case 5:	polygon2( bbuf );
			backupput( bbuf, gwork );	/* cancel */
			polygon2( bbuf );
			break;
		case 6:	polygon2( bbuf );
			sourcebox_display(cvar,ework);
			polysw = 1;
			if( polygon1( pp, bbuf ) )polysw = 0;	/* polygon */
			sourcebox_display(cvar,ework);
			break;
		case 7:	polygon2( bbuf );		/* polygon-off */
			polygon3( bbuf );
			polysw = 0;
			break;
		case 8:	sourcebox_display(cvar,ework);
			quad_check( pvar[0], cvar, ework );  /* trace */
			sourcebox_display(cvar,ework);
			break;
		case 9:	polygon2( bbuf );
			if(
			    error_check(
				mov_save_page(
				     (char *)pvar[5], mode, (int *)pvar[3]
				)
			    )
			){
				polygon3( bbuf );
				return -1;
			}
			polygon2( bbuf );
			break;				/* rec */
	}
	goto quad1;

quad7:	wt = 125000;
quad8:	if( sw == 1 )pvar[i] = pvar[i] + 1;
	if( sw == 2 )pvar[i] = pvar[i] - 1;
	if( pvar[i] < min )pvar[i] = max;
	if( pvar[i] > max )pvar[i] = min;
	quad_dsp(data,pvar);
	for( k = 0 ; k < wt ; k++ );
	wt = 10000;
	MOS_rdpos(&sw,&cx,&cy);
	if( sw > 0 )goto quad8;
	goto quad2;
}

quad_dsp(data,var)
int data[],var[];
{
	int i, x, y;
	int point[][3] = {	{ 552,463,3 },
				{ 192,479,3 }
			  };
	char dsp[10];

	for( i = 0 ; i < 2 ; i++ ){
		if( data[i] != var[i] ){
		x = point[i][0]; y = point[i][1];
			MOS_disp(0);
			itochar( var[i], point[i][2], dsp );
			gprint2( dsp, x, y );
			data[i] = var[i];
		}
	}
	return 0;
}

backupget(bbuf,gwork)		/* 保存 */
char *bbuf,*gwork;
{
	char para[8];

	DWORD(para+0) = (unsigned int)bbuf;
	DWORD(para+4) = 0x104;
	geta17(gwork,para);	/* polygon data 保存 1991 2/28 */
	return 0;
}

backupput(bbuf,gwork)		/* 画面バック(cancel) */
char *bbuf,*gwork;
{
	char para[12];

	DWORD(para+0) = (unsigned int)bbuf;
	DWORD(para+4) = 0x104;
	DWORD(para+8) = 12;	/* 1991 2/28 特設 */
	puta17(gwork,para);
	return 0;
}

sourcebox_display(var,ework)
int var[][2];
char *ework;
{
	char para[8];

	EGB_writePage(ework,0);		/* mode10に書き込み */
	EGB_color(ework,0,C_B);
	EGB_paintMode(ework,0x2);
	EGB_writeMode(ework,4);
	WORD(para + 0) = var[0][0];
	WORD(para + 2) = var[0][1];
	WORD(para + 4) = var[1][0];
	WORD(para + 6) = var[1][1];
	EGB_rectangle(ework,para);
	return 0;
}

rectangle_coodr( var, ework )
int var[][2];
char *ework;
{
	int sw, cx, cy, temp;
	int v[2][2], mp[3];

	display_scale();
	EGB_writePage(ework,0);		/* mode10に書き込み */
	MOS_horizon(0,319);
	MOS_vertical(0,239);
	MOS_setpos( 160, 120 );
	MOS_disp(0);
cood1:	mouse(mp,0,0,10);
	sw = mp[0]; cx = mp[1]; cy = mp[2];
	if( sw > 1 )goto cood3;
	v[0][0] = cx; v[0][1] = cy;
	mouse(mp,0,0,4);
	sw = mp[0]; cx = mp[1]; cy = mp[2];
	if( sw > 1 )goto cood1;
	if( cx == v[0][0] || cy == v[0][1] )goto cood3;
	v[1][0] = cx; v[1][1] = cy;
	if( v[0][0] > v[1][0] ){	/* 大小整頓 */
		temp = v[0][0];
		v[0][0] = v[1][0];
		v[1][0] = temp;
	}
	if( v[0][1] > v[1][1] ){
		temp = v[0][1];
		v[0][1] = v[1][1];
		v[1][1] = temp;
	}
	var[0][0]=v[0][0]; var[0][1]=v[0][1];
	var[1][0]=v[1][0]; var[1][1]=v[1][1];
cood3:	EGB_writePage(ework,1);		/* mode3に書き込み */
	MOS_horizon(0,639);
	MOS_vertical(0,479);
	MOS_setpos( 320, 240 );
	return 0;
}

quad_coodr( var, n, ework )
int var[][2],n;
char *ework;
{
	int sw, cx, cy, i, bn;
	int mp[3];
	int b[6][2];

	display_scale();
	EGB_writePage(ework,0);		/* mode10に書き込み */
	MOS_horizon(0,319);
	MOS_vertical(0,239);
	MOS_setpos( 160, 120 );
	MOS_disp(0);
cood1:	mouse( mp, 0, 0, 10 );
	sw = mp[0]; cx = mp[1]; cy = mp[2];
	if( sw > 1 )goto cood2;
	bn = 0; b[0][0] = cx; b[0][1] = cy;
	while( bn < 3 ){
		mouse( mp, 0, 0, 2 );
		sw = mp[0]; cx = mp[1]; cy = mp[2];
		if( sw > 1 ){
			if( bn == 0 )goto cood1;
			for( i=1 ; i<=bn ; i++ ){	/* やりなおし */
				line_set(
				 b[i-1][0], b[i-1][1], b[i][0], b[i][1], ework
				);
			}
			goto cood1;
		}
		bn++; b[bn][0] = cx; b[bn][1] = cy;	/* 次のステップ */
		line_set( b[bn-1][0], b[bn-1][1], b[bn][0], b[bn][1], ework );
	}
	bn = 4; b[4][0] = b[0][0]; b[4][1] = b[0][1];	/* 最後のライン */
	line_set( b[3][0], b[3][1], b[4][0], b[4][1], ework );
	for( i=1 ; i<=bn ; i++ ){			/* ライン消し */
		line_set( b[i-1][0], b[i-1][1], b[i][0], b[i][1], ework );
	}
	if( error_check( square_check( b ) ) )goto cood2;
	for( i=0 ; i<4 ; i++ ){
		var[i+n][0] = b[i][0];
		var[i+n][1] = b[i][1];
	}
cood2:	EGB_writePage(ework,1);		/* mode3に書き込み */
	MOS_horizon(0,639);
	MOS_vertical(0,479);
	MOS_setpos( 320, 240 );
	return 0;
}

quad_check( n, var, ework )
int n, var[][2];
char *ework;
{
	int i, j, mp[3], outvar[5][2];

	for( i=0 ; i<10 ; i++ ){
		if( var[i][0] < 0 ){	/* data check */
			error_check( 4 );
			return -1;
		}
	}
	EGB_writePage(ework,0);		/* mode10に書き込み */
	for( j=0 ; j<2 ; j++ ){
		if( j )mouse( mp, 0, 0, 0 );
		for( i=1 ; i<=n ; i++ ){
			quad_out( i, outvar, n, var );
			quad_line( outvar, ework );
		}
	}
	EGB_writePage(ework,1);		/* mode3に書き込み */
	return 0;
}

expand_copy( pvar, var, polysw, bbuf, ework, gwork )
int pvar[], var[][2], polysw;
char *bbuf, *ework, *gwork;
{
	int p, n, col;			/* page1 page0 color */
	int ax1, ay1, ax2, ay2;
	int temp, i, xmin, ymin, xmax, ymax, ax, ay, axm, aym, det;
	int bx0, by0, bx1, by1, bx2, by2, bx3, by3;
	int b[6][2], para[18];
	char para2[8];

	p = pvar[1]; n = pvar[0]; col = pvar[2];
	if( p > n )return 54;			/* error check */
	if( var[0][0] >= var[1][0] )return 4;
	if( var[0][1] >= var[1][1] )return 4;
	for( i=2 ; i<10 ; i++ ){
		if( var[i][0] < 0 )return 4;
	}
	EGB_writePage(ework,0);		/* mode10に書き込み */
	EGB_color(ework,0,col);		/* paint color set */
	EGB_color(ework,2,col);
	EGB_paintMode(ework,0x22);
	EGB_writeMode(ework,0);
	EGB_penSize(ework,1);
	WORD(para2 +0 ) = 0;
	WORD(para2 +2 ) = 0;
	WORD(para2 +4 ) = 319;
	WORD(para2 +6 ) = 239;
	EGB_rectangle( ework, para2 );
	quad_out( p, b, n, var );
	if( ( temp = square_check( b ) ) != 0 )goto expnd1;
	quad_line( b, ework );
	if( polysw == 0 )polygon_box( var, bbuf );	/* polygon */
	quad_line( b, ework );
	para[0] = (unsigned int)bbuf;
	para[1] = 0x104;
	ax1 = var[0][0]; ay1 = var[0][1];
	ax2 = var[1][0]; ay2 = var[1][1];
	xmin = b[0][0]; xmax = b[0][0]; ymin = b[0][1]; ymax = b[0][1];
	for( i=0 ; i<4 ; i++ ){				/* 最大,最小 */
		if( xmin > b[i][0] )xmin = b[i][0];
		if( xmax < b[i][0] )xmax = b[i][0];
		if( ymin > b[i][1] )ymin = b[i][1];
		if( ymax < b[i][1] )ymax = b[i][1];
	}
	bx0 = b[0][0]; by0 = b[0][1];
	bx1 = b[1][0] - bx0; by1 = b[1][1] - by0;
	bx2 = b[2][0] - bx0; by2 = b[2][1] - by0;
	bx3 = b[3][0] - bx0; by3 = b[3][1] - by0;
	ax = ax2 - ax1; ay = ay2 - ay1;
	det = bx1*by3 - bx3*by1;
	if( det == 0 ){
		temp = 100;
		goto expnd1;
	}
	para[2] =  ( ((double)ax)*by3*65536 )/det;
	para[3] = -( ((double)ax)*bx3*65536 )/det;
	para[4] = -( ((double)ay)*by1*65536 )/det;
	para[5] =  ( ((double)ay)*bx1*65536 )/det;
	axm = para[2]*bx2 + para[3]*by2;
	aym = para[4]*bx2 + para[5]*by2;
	if( (axm == 0) || (aym == 0) ){
		temp = 100;	/* axm*aym==0はerror god-transも同じ */
		goto expnd1;	/* overflow=0になる↑対処せよ91 2･25 */
	}
	para[6] = ( (double)( axm - ax*65536 ) )/ax/aym*65536;
	para[7] = ( (double)( aym - ay*65536 ) )/ay/axm*65536;
	para[8] = bx0; para[9] = by0;
	para[10] = ax1 * 65536; para[11] = ay1 * 65536;
	para[12] = xmin; para[13] = ymin; para[14] = xmax; para[15] = ymax;
	para[16] = 256;
	expand17( gwork, para );
expnd1:	if( polysw == 0 )poly1(bbuf);	/* polygon data clear */
	EGB_writePage(ework,1);		/* mode3に書き込み */
	return temp;
}

polygon_box( var, bbuf )	/* box area set */
int var[][2];
char *bbuf;
{
	int x1, x2, y, address;

	poly1(bbuf);			/* polygon data clear */
	x1 = var[0][0]; x2 = var[1][0];
	for( y=var[0][1] ; y<=var[1][1] ; y++ ){
		address = y * 1024 + x1 * 2;
		WORD( bbuf + address ) = WORD( bbuf + address ) | 0x8000;
		address = y * 1024 + x2 * 2;
		WORD( bbuf + address ) = WORD( bbuf + address ) | 0x8000;
	}
	poly2( bbuf, var[0][1], var[1][1] );
	return 0;
}

/* nページ分割 var[2][0]-var[9][2] → pページ出力 outvar[0][0]-outvar[3][2] */

quad_out( p, outvar, n, var )
int p, outvar[5][2], n, var[][2];
{
	int i, m, m1, m2;

	m = n - 1; m1 = p - 1; m2 = m - m1;
	for( i=0 ; i<4 ; i++ ){
		outvar[i][0] = ( m2*var[i+2][0] + m1*var[i+6][0] ) / m;
		outvar[i][1] = ( m2*var[i+2][1] + m1*var[i+6][1] ) / m;
	}
	outvar[4][0] = outvar[0][0]; outvar[4][1] = outvar[0][1];
	return square_check(outvar);		/* 外積チェック */
}

quad_line( var, ework )
int var[5][2];
char *ework;
{
	int i;

	for( i=1 ; i<=4 ; i++ ){			/* ライン */
	    line_set( var[i-1][0], var[i-1][1], var[i][0], var[i][1], ework );
	}
	return 0;
}

line_set( x1, y1, x2, y2, ework )
int x1, y1, x2, y2;
char *ework;
{
	char para[32];


	EGB_color(ework,0,C_WT);
	EGB_writeMode( ework, 4 );		/* XOR */
	EGB_paintMode( ework, 0x22 );
	WORD( para+0 ) = 2;
	WORD( para+2 ) = x1;
	WORD( para+4 ) = y1;
	WORD( para+6 ) = x2;
	WORD( para+8 ) = y2;
	EGB_unConnect( ework, para );
	return 0;
}

square_check(b)		/* 外積チェック */
int b[5][2];
{
	int data[4], a[4][2];

	a[0][0] = b[1][0] - b[0][0];	/* ベクトル */
	a[0][1] = b[1][1] - b[0][1];
	a[1][0] = b[2][0] - b[1][0];
	a[1][1] = b[2][1] - b[1][1];
	a[2][0] = b[3][0] - b[2][0];
	a[2][1] = b[3][1] - b[2][1];
	a[3][0] = b[0][0] - b[3][0];
	a[3][1] = b[0][1] - b[3][1];
	data[0] = a[0][0]*a[1][1] - a[0][1]*a[1][0];	/* 外積 */
	data[1] = a[1][0]*a[2][1] - a[1][1]*a[2][0];
	data[2] = a[2][0]*a[3][1] - a[2][1]*a[3][0];
	data[3] = a[3][0]*a[0][1] - a[3][1]*a[0][0];
	if( ((double)data[0])*data[1]*data[2]*data[3] > 0 )return 0;
	return 100;
}

