/*
	TOWNSモザイクプログラム
	                                      1995/02/15  N.M

    画面0のデ−タの一部をモザイク状に画面1にコピ−し実現
	TAB = 4 文字で表示してください

*/
#include <stdio.h>

char gwork[640*500] ;				/* グラフイックBIOSワーク 	*/
char mwork[4096] ;			 		/* マウスBIOSワーク 		*/

static struct DOT_PARA{				/* EGB用ﾊﾟﾗﾒ-ﾀ 				*/
		unsigned short int	*ptr;
		short int	ds;
		unsigned short int x1,y1,x2,y2;
} dot_para;

static unsigned short int dot_data[360*240];		/* 画面0のﾃﾞ-ﾀ取り込み用 */
static unsigned short int dot_data_out[360*240];	/* 画面1への出力用 */

static unsigned short int *dot_ptr;					/* ﾓｻﾞｲｸﾌﾞﾛｯｸの中心ｱﾄﾞﾚｽ */
													/* ﾜ-ｸ用ﾎﾟｲﾝﾀ */

static struct PARET {				/* V-SYNC検出用にﾊﾟﾚｯﾄ転送ﾀｲﾐﾝｸﾞを得る */
	int		suu;
	int		p_no;
	char	color[10];
} paret;

int		x_dot,y_dot;		/* ﾓｻﾞｲｸの処理ﾄﾞｯﾄ数  x および y 			*/
							/* ｶ-ｿﾙ位置を中心に x:横 y:縦 の処理ﾄﾞｯﾄ数 	*/
int		x_block,y_block;	/* ﾓｻﾞｲｸの数  1ﾌﾞﾛｯｸは 10*10ﾄﾞｯﾄで構成 		*/
int		x_min,x_max;		/* ｶ-ｿﾙの移動範囲 min:左  max:右 			*/
int		y_min,y_max;		/* ｶ-ｿﾙの移動範囲 min:上  max:下 			*/
int		g_x_level,g_y_level;/* ﾓｻﾞｲｸ画面の大きさ 0-5					*/

/* ﾌﾟﾛﾄﾀｲﾌﾟの設定 */
void	set_area(int);		/* ﾓｻﾞｲｸの処理範囲を設定	*/
void	set_max(int,int);	/* ﾓｻﾞｲｸ画面の範囲を設定 */

/********************************************************************/
/* 処理ﾌﾟﾛｸﾞﾗﾑ */
/********************************************************************/

void set_area(key)		/* ﾓｻﾞｲｸの処理範囲を設定	*/
int		key;
{
	/* 入力keyによってﾌﾞﾛｯｸのx,y方向を増減させる */
	if(key == 0x51) g_x_level++;	/* ｶ-ｿﾙの "→" */
	if(key == 0x4f) g_x_level--;	/* ｶ-ｿﾙの "←" */
	if(key == 0x4d) g_y_level++;	/* ｶ-ｿﾙの "↑" */
	if(key == 0x50) g_y_level--;	/* ｶ-ｿﾙの "↓" */
 
	/* 範囲の確認と設定 */
	if(g_x_level <  0) g_x_level =  0;	/* ﾌﾞﾛｯｸは　0以上 10以下 */
	if(g_x_level > 10) g_x_level = 10;
	if(g_y_level <  0) g_y_level =  0;
	if(g_y_level > 10) g_y_level = 10;

	/* ﾓｻﾞｲｸ処理のﾊﾟﾗﾒ-ﾀ設定 */
	set_max(g_x_level,g_y_level);

}

/********************************************************************/

void	set_max(g_x_level,g_y_level)	/* ﾓｻﾞｲｸ画面の範囲を設定 	*/
int		g_x_level;						/* 横方向の大きさ			*/
int		g_y_level;						/* 縦方向の大きさ			*/
{
		x_block = 2 + g_x_level * 2;	/* ﾓｻﾞｲｸﾌﾞﾛｯｸの大きさを計算 */
		y_block = 2 + g_y_level * 2;

		x_min	= x_block/2*10 + 10;	/* ｶ-ｿﾙ移動範囲の最小値		*/
		y_min	= y_block/2*10 + 10;	/* ｶ-ｿﾙ移動範囲の最小値		*/
		x_max	= 360 - x_min;			/* ｶ-ｿﾙ移動範囲の最大値		*/
		y_max	= 240 - y_min;			/* ｶ-ｿﾙ移動範囲の最大値		*/

		x_dot	= x_block * 10;			/* ﾓｻﾞｲｸ処理ﾄﾞｯﾄ数			*/
		y_dot	= y_block * 10;			/* ﾓｻﾞｲｸ処理ﾄﾞｯﾄ数			*/
}

/********************************************************************/

void main() 				/* MAIN処理 */
{
	int b, x, y ,old_x,old_y,xx,yy;		/* 内部変数 */
	unsigned int i,j,k,l,m;				/* ﾙ-ﾌﾟ変数､一時ﾎﾟｲﾝﾀ等   */
	int	key,kcnt;						/* keyﾎﾞ-ﾄﾞからの入力ｺ-ﾄﾞ */

	for(i=0;i<360*240;i++) {		/* 出力ﾃﾞ-ﾀBUFの初期設定 */
		dot_data_out[i]   = 0x8000;	/* 透過ﾓ-ﾄﾞで初期化      */
	};

	EGB_init( gwork, 640*500*2 ) ;	/* BIOSの初期化 */
	EGB_resolution( gwork, 0, 9 ) ;/* ページ0の解像度設定(32k色) */
	EGB_resolution( gwork, 1, 9 ) ;/* ページ1の解像度設定(32k色) */
	EGB_displayPage( 1,gwork, 2 ) ;	/* 表示ページの設定 画面1	 */
	EGB_backColor( gwork, (int)0x8000 );/*[07]	背景色の設定(パレットコード)*/
										/* 透過に設定 */

	EGB_writePage( gwork, 1 ) ;	/* 書き込みページを1に */
	EGB_clearScreen( gwork );  	/*[20]		VRAM領域の消去  */

	EGB_writePage( gwork, 0 ) ;	/* 書き込みページを0に */
	EGB_clearScreen( gwork );  	/*[20]		VRAM領域の消去  */

	EGB_digitize( gwork, 1);	/*[1B]	ディジタイズ　on   画面0 */

	MOS_start( mwork, 4096 ) ;	/* マウスの初期化 */
	MOS_resolution( 1, 9 ) ;	/* マウスへ1ページのﾓ-ﾄﾞに設定 	*/
	MOS_writePage( 1 ) ;		/* マウスは1ペ−ジに表示 		*/
	
	MOS_disp( 0 ) ;				/* マウスを表示しない 			*/


	EGB_writeMode( gwork,0 );  			/*[0A]	描画モードの設定 PSET */
	EGB_superImpose( gwork, 0x9999 ); 	/*[1A]	スーパーインポーズ ON */

	/* ﾊﾟﾗﾒ-ﾀの初期化 */
	g_x_level = 4;		/* ﾓｻﾞｲｸ画面の大きさを示す 横方向 */
	g_y_level = 4;		/* ﾓｻﾞｲｸ画面の大きさを示す 縦方向 */

	set_max(g_x_level,g_y_level);	/* ﾓｻﾞｲｸ画面の範囲を設定 */

	MOS_rdpos( &b, &x, &y ) ; /* マウス座標の読み取り */
		if(x < x_min) x = x_min;	/* x の移動範囲確認		 	*/
		if(x > x_max) x = x_max;
		if(y < y_min) y = y_min;	/* y の移動範囲確認		 	*/
		if(y > y_max) y = y_max;
	old_x     = x;
	old_y     = y;

	do {
		MOS_rdpos( &b, &x, &y ) ; /* マウス座標の読み取り 		*/
		if( b == 1 ) 	{	/* 左ボタンが押されたら ﾓｻﾞｲｸ中止 	*/

			/* ﾓｻﾞｲｸを書き込んでいる画面1をｸﾘｱ */
			EGB_digitize( gwork, 0); /*[1B]	ディジタイズ　off 	*/
			EGB_writePage( gwork, 1) ;	/* 書き込みページを1に 	*/
			EGB_clearScreen( gwork );  /*[20]		VRAM領域の消去  */
			EGB_writePage( gwork, 0 ) ;	/* 書き込みページを0に 	*/
			EGB_digitize( gwork, 1); /*[1B]	ディジタイズ　on 	*/

			/* 2V-sync間のwait ﾁｬﾀﾘﾝｸﾞ防止 */
			EGB_palette( gwork, (int)1, &paret ); /*[04]パレットの設定*/
			EGB_palette( gwork, (int)1, &paret ); /*[04]パレットの設定*/

			do {							/* 左ﾎﾞﾀﾝが押されるまでLoop */
				MOS_rdpos( &b, &x, &y ) ; 	/* マウス座標の読み取り 	*/
				if(x < x_min) x = x_min;	/* x の移動範囲確認		 	*/
				if(x > x_max) x = x_max;
				if(y < y_min) y = y_min;	/* y の移動範囲確認		 	*/
				if(y > y_max) y = y_max;
				old_x = x;
				old_y = y;

				/* 2V-sync間のwait ﾁｬﾀﾘﾝｸﾞ防止 */
				EGB_palette( gwork, (int)1, &paret ); /*[04]パレットの設定*/
				EGB_palette( gwork, (int)1, &paret ); /*[04]パレットの設定*/

				KYB_inpchk(&kcnt,&key);	/* 文字の読込 				*/ 
				KYB_clrbuf();			/* 文字ﾊﾞｯﾌｧのｸﾘｱ			*/
				if(kcnt != 0) {			/* 文字入力があれば取り込み */
					key = key /256;		/* 上位ﾊﾞｲﾄに文字ﾃﾞ-ﾀがある */
					set_area(key);		/* ﾓｻﾞｲｸの処理範囲を設定	*/
				};

				/* ﾓｻﾞｲｸﾊﾞｯﾌｧをｸﾘｱ 表示領域が変更されるため､ｸﾘｱ必要 */
				for(i=0;i<360*240;i++) {		/* 出力ﾃﾞ-ﾀBUFの初期設定 */
					dot_data_out[i]   = 0x8000;	/* 透過ﾓ-ﾄﾞで初期化      */
				};

				if(b == 2) {		/*  マウスの右ボタンが押されたら終了 */
					/* 終了時の処理 */
					MOS_end() ;		/*  マウスの停止  (忘れないように) */
					screenterm( gwork ) ;	/* MS-DOSの画面モードに設定する。
	                	           T-MENUから起動するプログラムの場合は不要 */
					exit(0);		/* 終了 */
				};
			} while( b != 1 );/* 左ボタンが押されたら Loopから抜けﾓｻﾞｲｸ ON */

			/* 2V-sync間のwait ﾁｬﾀﾘﾝｸﾞ防止 */
			EGB_palette( gwork, (int)1, &paret ); /*[04]パレットの設定*/
			EGB_palette( gwork, (int)1, &paret ); /*[04]パレットの設定*/
		};

		KYB_inpchk(&kcnt,&key);	/* 文字の読込 				*/ 
		KYB_clrbuf();			/* 文字ﾊﾞｯﾌｧのｸﾘｱ			*/
		if(kcnt != 0) {			/* 文字入力があれば取り込み */
			key = key /256;		/* 上位ﾊﾞｲﾄに文字ﾃﾞ-ﾀがある */
			set_area(key);		/* ﾓｻﾞｲｸの処理範囲を設定	*/

			x = old_x;			/* ﾓｻﾞｲｸの大きさ変更時は移動中止 */
			y = old_y;

			/* ﾓｻﾞｲｸﾊﾞｯﾌｧをｸﾘｱ 表示領域が変更されるため､ｸﾘｱ必要 */
			for(i=0;i<360*240;i++) {		/* 出力ﾃﾞ-ﾀBUFの初期設定 */
				dot_data_out[i]   = 0x8000;	/* 透過ﾓ-ﾄﾞで初期化      */
			};
		};

		xx = x - old_x;			/* x,y の移動量は9以下に制限 */
		yy = y - old_y;
		if(	abs(xx) >=10 )
			if( xx >= 0) { 
					x = old_x + 9;
			}	else {
				    x = old_x - 9;
			};
		if(	abs(yy) >=10 )
			if( yy >= 0) {
					y = old_y + 9;
			}	else {
				    y = old_y - 9;
			};
		if(x < x_min) x = x_min;	/* x の移動範囲確認		 	*/
		if(x > x_max) x = x_max;
		if(y < y_min) y = y_min;	/* y の移動範囲確認		 	*/
		if(y > y_max) y = y_max;
		old_x = x;
		old_y = y;
		
		/* ﾃﾞｼﾞﾀｲｽﾞ画面からﾃﾞ-ﾀを取り込む */
		/* EGBﾊﾟﾗﾒ-ﾀの設定 */
		dot_para.x1 = x - x_dot/2;		/* x,y 座標を設定 	*/
		dot_para.y1 = y - y_dot/2;
		dot_para.x2 = x + x_dot/2-1;	/* なぜか-1しないと数が合わない */
		dot_para.y2 = y + y_dot/2;
		dot_para.ptr = dot_data;		/* Bufferを指定 	*/
		dot_para.ds  = 0x0014;			/* Block転送 		*/
		
		EGB_getBlock( gwork, &dot_para ); 
						/*[24]	矩形領域読みだし(フルカラー)*/

		/* ﾓｻﾞｲｸを設定 */
		for(i=0;i<y_block;i++) {			/* y 方向 */
			for(j=0;j<x_block;j++) {		/* x 方向 */
				/* ﾓｻﾞｲｸﾌﾞﾛｯｸの中心の色をそのﾌﾞﾛｯｸの色にする */
				dot_ptr = &dot_data[(i*10+5)*x_dot+j*10+5];
									/* 10 x 10 の区画のうち(+5,+5)の点を使用 */
				/* ﾌﾞﾛｯｸを同一色で塗りつぶし */
				m =((i+1)*10)*(10+x_dot+10)+j*10+10; /* 処理ﾌﾞﾛｯｸの左上 */
				for(k=0;k<10;k++)					 /* y 方向			*/
					for(l=0;l<10;l++)				 /* x 方向			*/
						dot_data_out[m+l+k*(10+x_dot+10)] = *dot_ptr;
			};
		};

		/* ﾓｻﾞｲｸのﾃﾞ-ﾀを画面1に書き出す  ﾓｻﾞｲｸの設定 */
		/* x,y 座標を再設定 (読出と同一座標) */
		dot_para.x1 = x - x_dot/2 -10-3;	/* x,y 座標を設定 	*/
		dot_para.y1 = y - y_dot/2 -10;		/* xの -3 はｽ-ﾊﾟ-とCRTの位置合せ */
		dot_para.x2 = x + x_dot/2 +10-3-1;	/* なぜか-1しないと数が合わない */
		dot_para.y2 = y + y_dot/2 +10;
		dot_para.ptr = dot_data_out;		/* Bufferを指定 	*/
		dot_para.ds  = 0x0014;				/* Block転送 		*/


		EGB_digitize( gwork, 0); 			/*[1B]	ディジタイズ　off 		*/
		EGB_writePage( gwork, 1) ;			/* 書き込みページを1に 			*/
		EGB_putBlock( gwork, 0, &dot_para );/*[25]矩形領域書き込み(ﾌﾙｶﾗ-)	*/
		EGB_writePage( gwork, 0 ) ;			/* 書き込みページを0に 			*/
		EGB_digitize( gwork, 1); 			/*[1B]	ディジタイズ　on 		*/

	} while( b != 2 ) ;		/* 右ボタンでループを終わる 				*/

	/* 終了時の処理 */
	MOS_end() ;				/*  マウスの停止  (忘れないように) 			*/
	screenterm( gwork ) ;	/* MS-DOSの画面モードに設定する。
	                           T-MENUから起動するプログラムの場合は不要 */
}

