/*
			MOV DATA SAVE

			Hiroshi TODA
			1991 7/28
*/

#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include <mos.h>
#include "video.h"

#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 OK_COLOR 12		/* OK color palette */

extern quad_expand(int epvar[],int ecvar[][2],char *ework,char *gwork,char *bbuf);
extern int windget();
extern int gprint( char *, int x, int y );
extern int gprint2( char *, int x, int y );
extern int mouse( int mpara[], int, int, int );
extern int windput();
extern int error_check( int );
extern int filename( char *path, char *fullname );
extern int fileinput( char *fullname );
extern int itochar( int var, int n, char *dsp );
extern int display_scale();
extern int dezitize( int mode );

extern int sw,cx,cy;		/* MOUSE data */
extern int pn;			/* POLYGON point counter */

extern int col[][4];		/* paint & load  color data*/
extern int lvar[];			/* var. */
extern int svar[];
extern int epvar[];	/* page1, page2, color, svar-address, pn */
extern int ecvar[][2];
extern char path2[];		/* PATH NAME2 (graphic loader) */
extern char fullname2[];	/* PATH + FILES NAME2 */

extern int mpara[];		/* mouse para */
extern char para[];		/* PARAM */
extern char gwork[];	/* graph work */
extern char ework[];	/* EGB work */
extern char bbuf[];	/* BACK-UP buf. */
extern char rbuf[];	/* RAM-DISK buf. */
extern char rbuf2[];	/* RAM-DISK buf. */

/* filename → filename.mov */

mov_file_set( name, namemov )
char name[], namemov[];
{
	int i;

	for( i=0 ; i<76 ; i++ ){
		namemov[i] = name[i];
		if( name[i] == '.' || name[i] == (char)0 )goto mov01;
	}
	return 55;		/* bad file name */
mov01:	if( i == 0 )return 55;
	namemov[i++] = '.'; namemov[i++] = 'M'; namemov[i++] = 'O';
	namemov[i++] = 'V'; namemov[i] = (char)0;
	return 0;
}

/* mov2 head read */

mov_head_read(namemov, svar)
char *namemov;
int svar[];
{
	FILE *fp;
	int n, temp, page, size, data[64];
	char para[80];

	if( ( fp = fopen( namemov, "rb" ) ) == NULL )return 1;
	temp = fread( (char *)data, 1, 256, fp );
	if( temp < 256 )goto movh10;
	if( data[0] != 0x32564f4d )goto movh10;
	if( data[1] != 16 )goto movh10;
	if( data[4] != 320 )goto movh10;
	if( data[5] != 240 )goto movh10;
	svar[0] = data[3];			/* page  */
	svar[1] = data[2];			/* total */
	DWORD( para+0 ) = (unsigned int)bbuf;
	DWORD( para+4 ) = (unsigned int)rbuf;
	DWORD( para+8 ) = 0;
	DWORD( para+12) = 0;
	n = 0;
movh01:	temp = fread( bbuf, 1, 32, fp );
	if( temp < 32 )goto movh10;
	page = DWORD( bbuf ); size = DWORD( bbuf + 4 );
	if( (unsigned int)size > 500000 )goto movh10;
	temp = fread( bbuf+32, 1, size, fp );
	if( temp < size )goto movh10;
	WORD( bbuf+12 ) = 0;		/* wait なし */
	move32( para );
	n++;
	if( n < svar[0] )goto movh01;
	fclose( fp );
	return 0;
movh10:	fclose( fp );
	return 58;
}

/* mov replay */

mov_replay(namemov, p)
char *namemov;
int p;
{
	FILE *fpl;
	int temp, page, size, n, data[64];
	char para[16];

	if( ( fpl = fopen( namemov, "rb" ) ) == NULL )return 1;
	temp = fread( (char *)data, 1, 256, fpl );
	if( temp < 256 )goto rep10;
	if( data[0] != 0x564f4d )goto rep10;
	if( data[1] != 16 )goto rep10;
	if( data[4] != 320 )goto rep10;
	if( data[5] != 240 )goto rep10;
	DWORD( para+0 ) = (unsigned int)bbuf;
	DWORD( para+4 ) = (unsigned int)bbuf+0x40000;
	DWORD( para+8 ) = 0;
	DWORD( para+12) = 0;
	n = 0;
rep1:	if( n >= data[3] ){
		fclose( fpl );
		return 54;
	}
	temp = fread( bbuf, 1, 8, fpl );
	if( temp < 8 )goto rep10;
	page = DWORD( bbuf ); size = DWORD( bbuf + 4 );
	if( (unsigned int)size > 500000 )goto rep10;
	temp = fread( bbuf+8, 1, size, fpl );
	if( temp < size )goto rep10;
	move32_o( para );
	n++;
	if( n < p )goto rep1;
rep8:	fclose( fpl );
	return 0;
rep10:	fclose( fpl );
	return 58;
}

/* 新mov2 replay  mode=1:page判定 */

mov_replay2(namemov, p, mode)
char *namemov;
int p, mode;
{
	FILE *fpl;
	int temp, page, size, n, data[64];
	char para[80];

	if( ( fpl = fopen( namemov, "rb" ) ) == NULL )return 1;
	temp = fread( (char *)data, 1, 256, fpl );
	if( temp < 256 )goto rep10;
	if( data[0] != 0x32564f4d )goto rep10;
	if( data[1] != 16 )goto rep10;
	if( data[4] != 320 )goto rep10;
	if( data[5] != 240 )goto rep10;
	DWORD( para+0 ) = (unsigned int)bbuf;
	DWORD( para+4 ) = (unsigned int)bbuf+0x40000;
	DWORD( para+8 ) = 0;
	DWORD( para+12) = 0;
	n = 0;
rep1:	if( n >= data[3] && mode ){
		fclose( fpl );
		return 54;
	}
	temp = fread( bbuf, 1, 32, fpl );
	if( temp < 32 )goto rep10;
	page = DWORD( bbuf ); size = DWORD( bbuf + 4 );
	if( (unsigned int)size > 500000 )goto rep10;
	temp = fread( bbuf+32, 1, size, fpl );
	if( temp < size )goto rep10;
	WORD( bbuf+12 ) = 0;		/* wait なし */
	move32( para );
	n++;
	if( n < p )goto rep1;
rep8:	fclose( fpl );
	return 0;
rep10:	fclose( fpl );
	return 58;
}

/* GUI graphic loader */

graphic_load( path, fullname )
char path[64], fullname[80];
{
	char nametif[80];	/* tiff file name */
	char namemov[80];	/* mov file name */
	int min,max,i,j,k,wt,x0=0,y0=0,x1=0,y1=0;
	int data[10];
	char dsp1[] = "<<LOAD>> (B   R   G  )   MODE(      ,    )  MIX       MOVE(page   )  FILES  EXIT";
	char dsp2[] = "TIFF  FREE(x    y    o    )  NAME <<                                          >>";

load01:	windget();
	gprint( dsp1, 0, 463 );
	gprint( dsp2, 0, 479 );
	gprint2( fullname, 296, 479 );
	for( i = 0 ; i < 10 ; i++ )data[i] = -1;
	graphic_load_dsp(data);
load02:	col[0][0] = col[0][1]+(col[0][2] << 5)+(col[0][3] << 10);
	DWORD(para+0) = 1;			/* files背景色 */
	DWORD(para+4) = 14;
	DWORD(para+8) = (col[0][1] << 3)+(col[0][2] << 11)+(col[0][3] << 19);
	EGB_palette(ework,1,para);
	EGB_color( ework, 0, 14 );
	gprint( "■", 176, 463 );
	EGB_color( ework, 0, C_COLOR );
	MOS_disp(1);
	mouse(mpara,0,0,1);
	if( cy < 447 )goto load02;
	if( cy < 463 ){
		if( cx < 72 )goto load02;
		if( cx < 108 ){			/* B */
			i = 5; min = 0; max = 31;
			goto load07;
		}
		if( cx < 140 ){			/* R */
			i = 6; min = 0; max = 31;
			goto load07;
		}
		if( cx < 176 ){			/* G */
			i = 7; min = 0; max = 31;
			goto load07;
		}
		if( cx < 192 ){			/* spuit -> 7 */
			j = 7;
			goto load03;
		}
		if( cx < 292 ){			/* mode1 */
			i = 3; min = 0; max = 3;
			goto load07;
		}
		if( cx < 344 ){			/* mode2 */
			i = 8; min = 0; max = 1;
			goto load07;
		}
		if( cx < 408 ){			/* mix */
			i = 4; min = 0; max = 256;
			goto load07;
		}
		if( cx < 424 )goto load02;
		if( cx < 468 ){			/* move -> 6 */
			j = 6;
			goto load03;
		}
		if( cx < 544 ){			/* page */
			i = 9; min = 1; max = 999;
			goto load07;
		}
		if( cx < 600 ){			/* files -> 1 */
			j = 1;
			goto load03;
		}
		if( cx < 640 ){			/* exit -> 2 */
			j = 2;
			goto load03;
		}
		goto load02;
	}
	if( cy < 480 ){
		if( cx < 40 ){			/* tiff load -> 3 */
			j = 3;
			goto load03;
		}
		if( cx < 84 ){			/* free load -> 4 */
			j = 4;
			goto load03;
		}
		if( cx < 124 ){			/* X */
			i = 0; min = 1; max = 512;
			goto load07;
		}
		if( cx < 164 ){			/* Y */
			i = 1;
			min = 1; max = 512;
			goto load07;
		}
		if( cx < 224 ){			/* offset */
			i = 2;
			min = 0; max = 9999;
			goto load07;
		}
		if( cx < 640 ){			/* file name -> 5 */
			j = 5;
			goto load03;
		}
		goto load02;
	}
	goto load02;
load03:	mouse(mpara,0,0,0);
	if( sw > 1 )goto load02;
	MOS_disp(0);
	windput();
	switch( j ){
		case 1: filename( path, fullname );
			break;
		case 2: return 0;
		case 3: tif_file_set( fullname, nametif );
			error_check( tif_load( nametif, lvar, col[0][0] ) );
			return 0;
		case 4: error_check( freeload( fullname, lvar, col[0][0] ) );
			return 0;
		case 5: fileinput( fullname );
			break;
		case 6: mov_file_set( fullname, namemov );
			error_check( replay_load(namemov, lvar, col[0][0]) );
			return 0;
		case 7:	mode10_color_spuit( col );
			break;
	}
	goto load01;
load07:	wt = 125000;
	lvar[5] = col[0][1];
	lvar[6] = col[0][2];
	lvar[7] = col[0][3];
load08:	if( sw == 1 )lvar[i] = lvar[i] + 1;
	if( sw == 2 )lvar[i] = lvar[i] - 1;
	if( lvar[i] < min )lvar[i] = max;
	if( lvar[i] > max )lvar[i] = min;
	col[0][1] = lvar[5];
	col[0][2] = lvar[6];
	col[0][3] = lvar[7];
	graphic_load_dsp(data);
	for( k = 0 ; k < wt ; k++ );
	wt = 10000;
	MOS_rdpos(&sw,&cx,&cy);
	if( sw > 0 )goto load08;
	goto load02;
}

graphic_load_dsp(data)
int data[8];
{
	int i, x, y;
	int point[][3] = {	{  96,479,3 },
				{ 136,479,3 },
				{ 176,479,4 },
				{ 240,463,5 },
				{ 376,463,3 },
				{  88,463,2 },
				{ 120,463,2 },
				{ 152,463,2 },
				{ 296,463,5 },	/* 1990 9/6 for fix or mov */
				{ 504,463,3 }	/* 1991 2/16 for move page */
			  };
	char dsp[10];

	lvar[5] = col[0][1];
	lvar[6] = col[0][2];
	lvar[7] = col[0][3];
	col[0][0] = col[0][1]+(col[0][2] << 5)+(col[0][3] << 10);
	for( i = 0 ; i < 10 ; i++ ){
		if( data[i] != lvar[i] ){
			MOS_disp(0);
			itochar( lvar[i], point[i][2], dsp );
			EGB_color(ework,0,C_COLOR);
			x = point[i][0];  y = point[i][1];
			if( (i!=3) && (i!=8) )gprint2( dsp, x, y );
			if( i == 3 ){
				if( lvar[3]==0 )gprint2( "normal", x, y );
				if( lvar[3]==1 )gprint2( "ovlay ", x, y );
				if( lvar[3]==2 )gprint2( "chrma ", x, y );
				if( lvar[3]==3 )gprint2( "plygn ", x, y );
			}
			if( i == 8 ){
				if( lvar[8]==0 )gprint2( "fix ", x, y );
				if( lvar[8]==1 )gprint2( "move", x, y );
			}
			data[i] = lvar[i];
		}
	}
	return 0;
}

/* filename → filename.tif */

tif_file_set( name, nametif )
char name[], nametif[];
{
	int i;

	for( i=0 ; i<76 ; i++ ){
		nametif[i] = name[i];
		if( name[i] == '.' || name[i] == (char)0 )goto mov01;
	}
	return 55;		/* bad file name */
mov01:	if( i == 0 )return 55;
	nametif[i++] = '.'; nametif[i++] = 'T'; nametif[i++] = 'I';
	nametif[i++] = 'F'; nametif[i] = (char)0;
	return 0;
}

freeload( fullname, lvar, color )
char *fullname;
int lvar[], color;
{
	FILE *fpl;
	int size, xd, yd, temp, temp2;
	int xb1, yb1, xb2, yb2;
	char para[64];

	size = lvar[0] * lvar[1] * 2;
	xd = lvar[0] - 1;
	yd = lvar[1] - 1;
	if( lvar[8] ){					/* move */
		display_scale();
		EGB_writePage(ework,0);		/* mode10に書き込み */
		MOS_horizon(0,319);
		MOS_setpos( xd >> 1, yd >> 1 );
		mouse(mpara,xd,yd,6);
		EGB_writePage(ework,1);		/* mode3に書き込み */
		MOS_horizon(0,639);
		MOS_setpos( 320, 240 );
		if( sw > 1 )return 0;
	}
	if( ( fpl = fopen( fullname, "rb" ) ) == NULL ){
		return 1;
	}
	fseek( fpl, lvar[2], SEEK_SET );
	temp = fread( bbuf, 1, size, fpl );
	temp2 = ferror( fpl );
	fclose( fpl );
	if( lvar[8] ){
		xb1 = cx - (xd >> 1);
		yb1 = cy - (yd >> 1);
	}
	else { xb1 = 0; yb1 = 0; }
	if( temp < size )yd = temp/2/(xd+1) - 1;	/* too small data */
	if( yd < 0 )yd = 0;
	xb2 = xb1 + xd;
	yb2 = yb1 + yd;
	DWORD(para+0) =  (unsigned int)bbuf;		/* polygon bit 反転 */
	DWORD(para+4) =  0x104;
	DWORD(para+8) =  10;
	puta17( gwork, para );
	DWORD(para+0) = (unsigned int)bbuf;
	DWORD(para+4) = 0x104;
	DWORD(para+8) = xb1;
	DWORD(para+12) = yb1;
	DWORD(para+16) = xb2;
	DWORD(para+20) = yb2;
	DWORD(para+24) = lvar[3];
	DWORD(para+28) = color;
	DWORD(para+32) = lvar[4];
	put17(gwork,para);
	if( temp2 )return 1;
	return 0;
}

tif_load( fullname, lvar, color )
char *fullname;
int lvar[], color;
{
	FILE *fpl;
	int size, xd, yd, temp, temp2;
	int xb1, yb1, xb2, yb2;
	char para[64];

	if( ( fpl = fopen( fullname, "rb" ) ) == NULL ){
		return 1;
	}
		/* head read & seek to top data */
	if( tif_head_read( fpl, gwork, &xd, &yd ) == -1 ){
		fclose( fpl );
		return 58;
	}
	size = xd * yd * 2;
	xd = xd - 1; yd = yd - 1;
	if( lvar[8] ){					/* move */
		display_scale();
		EGB_writePage(ework,0);		/* mode10に書き込み */
		MOS_horizon(0,319);
		MOS_setpos( xd >> 1, yd >> 1 );
		mouse(mpara,xd,yd,6);	/* ydは変わる可能性有り */
		EGB_writePage(ework,1);		/* mode3に書き込み */
		MOS_horizon(0,639);
		MOS_setpos( 320, 240 );
		if( size > 512*512*2 )size = 512*512*2;	/* ovar buffer area */
		if( sw > 1 ){
			fclose( fpl );
			return 0;
		}
	}
	temp = fread( bbuf, 1, size, fpl );
	temp2 = ferror( fpl );
	fclose( fpl );
	if( lvar[8] ){
		xb1 = cx - (xd >> 1);
		yb1 = cy - (yd >> 1);
	}
	else { xb1 = 0; yb1 = 0; }
	yd = size/2/(xd+1) - 1;
	if( temp < size )yd = temp/2/(xd+1) - 1;	/* too small data */
	if( yd < 0 )yd = 0;
	xb2 = xb1 + xd;
	yb2 = yb1 + yd;
	DWORD(para+0) =  (unsigned int)bbuf;	/* polygon bit 反転 */
	DWORD(para+4) =  0x104;
	DWORD(para+8) =  10;
	puta17( gwork, para );
	DWORD(para+0) = (unsigned int)bbuf;
	DWORD(para+4) = 0x104;
	DWORD(para+8) = xb1;
	DWORD(para+12) = yb1;
	DWORD(para+16) = xb2;
	DWORD(para+20) = yb2;
	DWORD(para+24) = lvar[3];
	DWORD(para+28) = color;
	DWORD(para+32) = lvar[4];
	put17(gwork,para);
	EGB_clearScreen(ework);			/* mode 3 clear */
	if( temp2 )return 1;
	return 0;
}

tif_head_read( fpl, work, x, y )
FILE *fpl;
char work[];
int *x, *y;
{
	int i, m, n, size, tag, type, count, data, length;

	*x = -1; *y = -1; size = -1;
	m = 0;				/* total data count */
	if( fread( work, 1, 512, fpl ) < 512 )return -1;
	m = DWORD( work + 4 );		/* m = offset to IFD */
	if( (unsigned int)m > 511 )return -1;
	n = WORD( work + m );		/* タグの数 */
	m = m + 2;
	if( (unsigned int)n > 40 )n = 40;  /* タグは40まで(512Byteを越える) */
	if( (unsigned int)(m + n*12) > 511 )return -1;
	for( i=0 ; i<n ; i++ ){
		tag   = WORD(  work + m + 0 );
		type  = WORD(  work + m + 2 );
		count = DWORD( work + m + 4 );
		data  = DWORD( work + m + 8 );
		if( type == 2 )goto head01;		/* type2 : ASII */
		if( type == 5 )goto head01;		/* type5 : RATIONAL */
		length = type;				/* length check */
		if( type == 3 )length = 2;
		if( count*length > 4 )goto head01;	/* offset無視 */
		if( type == 1 )data = data & 0xff;	/* type1 : BYTE */
		if( type == 3 )data = data & 0xffff;	/* type3 : WORD */
		if( tag == 0x100 )*x = data;
		if( tag == 0x101 )*y = data;
		if( ( tag == 0x102 ) && ( data != 16 ) )return -1;
		if( tag == 0x111 )size = data;
	head01:	m = m + 12;
	}
	if( (*x<=0) || (*y<=0) || (size<=0) )return -1;
	if( size != 512 )fseek( fpl, size, SEEK_SET );
	return 0;
}

replay_load(namemov, lvar, color)
char *namemov;
int lvar[], color;
{
	int temp;

	DWORD(para+0) = (unsigned int)bbuf;	/* 画面1 -> bbuf */
	DWORD(para+4) = 0;
	DWORD(para+8) = 0x104;
	DWORD(para+12) = 245760;
	getbrock(gwork,para);
	DWORD(para+4) = 0x40000;		/* bbuf -> 画面2 */
	putbrock(gwork,para);
	temp = mov_replay2( namemov, lvar[9], 1 );
	if( temp == 58 )temp = mov_replay( namemov, lvar[9] );
	if( (lvar[3] == 0) && (lvar[4] == 256) )goto rep1;
	DWORD(para+0) = (unsigned int)bbuf;	/* 画面1 -> bbuf */
	DWORD(para+4) = 0;
	DWORD(para+8) = 0x104;
	DWORD(para+12) = 245760;
	getbrock(gwork,para);
	DWORD(para+0) = (unsigned int)bbuf+0x40000;	/* 画面2 -> bbuf2 */
	DWORD(para+4) = 0x40000;
	DWORD(para+8) = 0x104;
	DWORD(para+12) = 245760;
	getbrock(gwork,para);
	DWORD(para+4) = 0;			/* bbuf2 -> 画面 */
	putbrock(gwork,para);
	DWORD(para+0) =  (unsigned int)bbuf;	/* polygon bit 反転 */
	DWORD(para+4) =  0x104;
	DWORD(para+8) =  10;
	puta17( gwork, para );
	DWORD(para+0) = (unsigned int)bbuf;
	DWORD(para+4) = 0x104;
	DWORD(para+8) = 0;
	DWORD(para+12) = 0;
	DWORD(para+16) = 511;
	DWORD(para+20) = 239;
	DWORD(para+24) = lvar[3];
	DWORD(para+28) = color;
	DWORD(para+32) = lvar[4];
	put17(gwork,para);
rep1:	return temp;
}

mode10_color_spuit( color )
int color[];
{
	EGB_writePage(ework,0);		/* mode10に書き込み */
	MOS_horizon(0,319);
	MOS_vertical(0,239);
	MOS_setpos( 160, 120 );
	MOS_disp(0);
spuit1:	mouse(mpara,0,0,10);
	if( sw > 1 )goto spuit2;
	color[0] = peekw( 1024*cy+2*cx, 0x104 ) & 0x7fff;
	color[1] = color[0] & 0x1f;
	color[2] = ( color[0] >> 5 ) & 0x1f;
	color[3] = ( color[0] >> 10 ) & 0x1f;
spuit2:	EGB_writePage(ework,1);			/* mode3に書き込み */
	MOS_horizon(0,639);
	MOS_vertical(0,479);
	MOS_setpos( 320, 240 );
	return 0;
}

mov_save( namemov )
char *namemov;
{
	int min,max,i,j,k,wt,mode;
	int data[13];
	char dsp1[] = "<<REC  page            Byte>> LOAD  VIDEO  EXPAND  ROUGH=    PRE-M0VE=      EXIT";
	char dsp2[] = " REC1  REC2  REPLAY(page   )  AREA(   ,   )-(   ,   ) BACK-COLOR=(B   R   G  )  ";

/*	svar[2] = 8; */			/* rough */
/*	svar[3] = 0; */			/* pre-move */
	svar[4] = 0; svar[5] = 0;	/* 座標 */
	svar[6] = 319; svar[7] = 239;
	svar[11] = -1;			/* replay page */
/*	svar[12] = */		/* リザーブ */
save1:	windget();
	if( svar[0] && svar[11] < 0 )svar[11] = 1;	/* replay 解除 */
	gprint( dsp1, 0, 463 );
	gprint( dsp2, 0, 479 );
	EGB_color(ework,0,E_COLOR);
	gprint( " REC1  REC2", 0, 479 );
	EGB_color(ework,0,OK_COLOR);
	gprint( "EXIT", 608, 463 );
	EGB_color(ework,0,C_COLOR);
	for( i = 0 ; i < 13 ; i++ )data[i] = 0xffff;
	mov_save_dsp(data,svar);
save2:	col[1][0] = col[1][1]+(col[1][2] << 5)+(col[1][3] << 10);
	DWORD(para+0) = 1;			/* files背景色 */
	DWORD(para+4) = 14;
	DWORD(para+8) = (col[1][1] << 3)+(col[1][2] << 11)+(col[1][3] << 19);
	EGB_palette(ework,1,para);
	EGB_color( ework, 0, 14 );
	gprint( "■", 624, 479 );
	EGB_color( ework, 0, C_COLOR );
	MOS_disp(1);
	mouse(mpara,  0, 0, 1);
	if( cy < 447 )goto save2;
	if( cy < 463 ){
		if( cx < 232 )goto save2;
		if( cx < 280 ){			/* LOAD 0 */
			j = 0;
			goto save3;
		}
		if( cx < 336 ){			/* dezitize 1 */
			j = 1;
			goto save3;
		}
		if( cx < 400 ){			/* expand 6 */
			j = 6;
			goto save3;
		}
		if( cx < 480 ){			/* rough */
			i = 2; min = 0; max = 99;
			goto save7;
		}
		if( cx < 584 ){			/* pre move */
			i = 3; min = 0; max = 16;
			goto save7;
		}
		if( cx < 600 )goto save2;
		if( cx < 640 ){			/* exit 2 */
			j = 2;
			goto save3;
		}
		goto save2;
	}
	if( cy < 480 ){
		if( cx < 48 ){			/* rec1 */
			mode = 0;
			j = 3;
			goto save3;
		}
		if( cx < 96 ){			/* rec2 */
			mode = 1;
			j = 3;
			goto save3;
		}
		if( cx < 152 ){			/* replay 4 */
			if( svar[0] == 0 )goto save2;
			j = 4;
			goto save3;
		}
		if( cx < 232 ){			/* page */
			if( svar[0] == 0 )goto save2;
			i = 11; min = 1; max = svar[0];
			goto save7;
		}
		if( cx < 276 ){			/* area 5 */
			j = 5;
			goto save3;
		}
		if( cx < 308 ){			/* x1 */
			i = 4; min = 0; max = 319;
			goto save7;
		}
		if( cx < 348 ){			/* y1 */
			i = 5; min = 0; max = 239;
			goto save7;
		}
		if( cx < 388 ){			/* x2 */
			i = 6; min = 0; max = 319;
			goto save7;
		}
		if( cx < 432 ){			/* y2 */
			i = 7; min = 0; max = 239;
			goto save7;
		}
		if( cx < 520 )goto save2;
		if( cx < 556 ){			/* b */
			i = 8; min = 0; max = 31;
			goto save7;
		}
		if( cx < 588 ){			/* r */
			i = 9; min = 0; max = 31;
			goto save7;
		}
		if( cx < 624 ){			/* g */
			i = 10; min = 0; max = 31;
			goto save7;
		}
		if( cx < 640 ){			/* spuit 7 */
			j = 7;
			goto save3;
		}
		goto save2;
	}
	goto save2;
save3:	mouse(mpara,  0, 0, 0);
	if( sw > 1 )goto save2;
	MOS_disp(0);
	windput();
	switch( j ){
		case 0: graphic_load( path2, fullname2 );	/* load */
			break;
		case 1:	dezitize(0);			/* dezitize */
			break;
		case 2:	error_check( mov_save_end(namemov,svar) ); /* exit */
			return 0;
		case 3:	if(
			    error_check( mov_save_page(namemov,mode,svar) )
			)return 0;
			break;
		case 4:	error_check( mov_replay2( namemov, svar[11], 0 ) );
			break;
		case 5: mov_save_coodr(svar);		/* area */
			break;
		case 6:	epvar[2] = col[1][0];		/* expand */
			epvar[3] = (unsigned int)svar;
			epvar[4] = pn;
			epvar[5] = (unsigned int)namemov;
			if(quad_expand(epvar,ecvar,ework,gwork,rbuf2))return 0;
			break;
		case 7:	mode10_color_spuit( *(col+1) );
			break;
	}
	goto save1;

save7:	wt = 125000;
	svar[8] = col[1][1];
	svar[9] = col[1][2];
	svar[10] = col[1][3];
save8:	if( sw == 1 )svar[i] = svar[i] + 1;
	if( sw == 2 )svar[i] = svar[i] - 1;
	if( svar[i] < min )svar[i] = max;
	if( svar[i] > max )svar[i] = min;
	col[1][1] = svar[8];
	col[1][2] = svar[9];
	col[1][3] = svar[10];
	mov_save_dsp(data,svar);
	for( k = 0 ; k < wt ; k++ );
	wt = 10000;
	MOS_rdpos(&sw,&cx,&cy);
	if( sw > 0 )goto save8;
	goto save2;
}

mov_save_dsp(data,var)
int data[],var[];
{
	int i, x, y;
	int point[][3] = {	{  88,463,3 },
				{ 120,463,8 },

				{ 456,463,2 },	/* rough rate */
				{ 560,463,2 },	/* pre move */

				{ 280,479,3 },	/* 座標 */
				{ 312,479,3 },
				{ 360,479,3 },
				{ 392,479,3 },

				{ 536,479,2 },	/* color */
				{ 568,479,2 },
				{ 600,479,2 },

				{ 192,479,3 },	/* page */
			  };
	char dsp[10];

	svar[8] = col[1][1];
	svar[9] = col[1][2];
	svar[10] = col[1][3];
	col[1][0] = col[1][1]+(col[1][2] << 5)+(col[1][3] << 10);
	EGB_color(ework,0,C_COLOR);
	for( i = 0 ; i < 12 ; 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;
}

mov_save_coodr( svar )
int svar[];
{
	display_scale();
	EGB_writePage(ework,0);		/* mode10に書き込み */
	MOS_horizon(0,319);
	MOS_vertical(0,239);
	MOS_setpos( 160, 120 );
	MOS_disp(0);
save1:	mouse(mpara,0,0,10);
	if( sw > 1 )goto save2;
	svar[4] = cx; svar[5] = cy;
	mouse(mpara,0,0,4);
	if( sw > 1 )goto save1;
	if( cx == svar[4] || cy == svar[5] )goto save2;
	svar[6] = cx; svar[7] = cy;
save2:	EGB_writePage(ework,1);			/* mode3に書き込み */
	MOS_horizon(0,639);
	MOS_vertical(0,479);
	MOS_setpos( 320, 240 );
	return 0;
}

mov_save_trim( svar )
int svar[];
{
	int color, x, y, temp, i, j;

	color = svar[8]+(svar[9] << 5)+(svar[10] << 10);
	for( i=0 ; i<153600 ; i+=4 ){	/* r-buffer top bit clear */
		DWORD( rbuf+i ) &= 0x7fff7fff;
	}
	for( j=0 ; j<245760 ; j+=4 ){	/* vram top bit clear */
		poked( j, 0x104, ( peekd( j, 0x104 ) & 0x7fff7fff ) );
	}
	if( svar[4] > svar[6] ){
		temp = svar[6]; svar[6] = svar[4]; svar[4] = temp;
	}
	if( svar[5] > svar[7] ){
		temp = svar[7]; svar[7] = svar[5]; svar[5] = temp;
	}
	if(    svar[4] == 0	/* full area -> return */
	    && svar[5] == 0
	    && svar[6] == 319
	    && svar[7] == 239
	)return 0;
	for( y=0 ; y<240 ; y++ ){
		for( x=0 ; x<320 ; x++ ){
			if(     x < svar[4]
			    ||  x > svar[6]
			    ||  y < svar[5]
			    ||  y > svar[7]
			){
				i = y*640 + x*2;	/* buffer add */
				j = (y << 10) + (x << 1);	/* vram */
				if( svar[0] ){
					WORD( rbuf+i ) |= 0x8000;
					xorw( j, 0x104, 0xffff );
				}
				else pokew( j, 0x104, color );
			}
		}
	}
	return 0;
}

mov_save_end( namemov, svar )
char *namemov;
int svar[];
{
	FILE *fps;
	int i, temp, data[2];

	if( svar[0] == 0 )return 0;
	for( i=0 ; i<6 ; i++ ){		/* disk write protect の場合6回必要 */ 
		if( ( fps = fopen( namemov, "r+b" ) ) != NULL )goto save2;
	}
	return 2;
save2:	data[0] = svar[1]; data[1] = svar[0];	/* data長 page */
	fseek( fps, 8, SEEK_SET );
	fwrite( (char *)data, 1, 8, fps );
	temp = ferror( fps );
	fclose( fps );
	if( temp ){
		remove( namemov );		/* error */
		return 2;
	}
	return 0;
}

/* save心臓部 */

mov_save_page( namemov, mode, svar )
char *namemov;
int mode, svar[];
{
	FILE *fps;
	int data;
	int a1, a2, i, j, k, temp;
	int n;

	/* mov head */
	int mvhead1[] = { 0x32564f4d, 16, 0, 0, 320, 240, 640 };
	int mvhead2[228]; 
	int pghead[8];

	for( k=0 ; k<228 ; k++ )mvhead2[k] = 0;
	temp = 0;
	mov_save_trim( svar );			/* trimming */
		/* 画面のはみ出した部分をclear */
	EGB_writePage(ework,0);			/* mode10設定 */
	EGB_color(ework,0,0);			/* clear paint */
	EGB_color(ework,2,0);
	EGB_paintMode(ework,0x22);
	EGB_writeMode(ework,0);
	EGB_penSize(ework,1);
	WORD(para+0) = 320;
	WORD(para+2) = 0;
	WORD(para+4) = 511;
	WORD(para+6) = 239;
	EGB_rectangle(ework,para);
	EGB_writePage(ework,1);			/* mode3に書き込み */
	EGB_color(ework,0,C_COLOR);
	if( svar[0] == 0 ){		/* page 0 */
		for( k=0 ; k<131072 ; k+=4 ){ /* rbufを使って最多色検索 */
			DWORD( rbuf+k ) = 0;	/* clear */
		}
		for( k=0 ; k<76800 ; k++ ){
			data = peekw( ((k/320) << 10)+((k%320) << 1), 0x104 );
			j = data << 2;
			DWORD( rbuf+j ) +=1;
		}
		n = 0; data = 0;
		for( k=0 ; k<32768 ; k++ ){
			if( DWORD( rbuf+(k << 2) ) > n ){
				n = DWORD( rbuf+(k << 2) );
				data = k;
			}
		}
		for( k=0 ; k<153600 ; k+=2 ){	/* 塗り潰し */
			WORD( rbuf+k ) = data;
			j = ( (k/640) << 10 ) + ( k % 640 );
			if(
			 mov_save_cmp_data( data,peekw(j,0x104),svar[2] ) == 0
			){
				WORD( rbuf+k ) = data | 0x8000;	/* 処理印 */
				xorw( j, 0x104, 0xffff );
			}
		}
			/* 孤立した点は処理解除 */
		for( k=2 ; k<153598 ; k+=2 ){
			if( (DWORD( rbuf+k ) & 0x80008000) == 0x8000
			&& (WORD( rbuf+k-2 ) & 0x8000) == 0 ){
				WORD( rbuf+k ) &= 0x7fff;
				j = ( (k/640) << 10 ) + ( k % 640 );
				xorw( j, 0x104, 0xffff );
			}
		}
		i = 0;				/* data counter */
		if( mode )WORD( bbuf+i ) = 4;	/* brock 数 */
		else WORD( bbuf+i ) = 3;	/* brock 数 */
		i+=2;
		WORD( bbuf+i ) = 0x1422; i+=2;	/* stosd brock */
		DWORD( bbuf+i ) = 17; i+=4;	/* data size */
		WORD( bbuf+i ) = 1; i+=2;	/* data 数 */
		DWORD( bbuf+i ) = data + ( data << 16 ); i+=4; /* data */
		WORD( bbuf+i ) = 1; i+=2;	/* offset 数 */
		WORD( bbuf+i ) = 0x0000; i+=2;	/* offset */
		WORD( bbuf+i ) = 1; i+=2;	/* data 個数 */
		WORD( bbuf+i ) = 0x0000; i+=2;	/* 下位 address */
		BYTE( bbuf+i ) = 0xff; i+=1;	/* 長さ */
		WORD( bbuf+i ) = 38400; i+=2;
		if( mode )i = mov_save_stosw0( i, svar ); /* stosw 0type */
		i = mov_save_stosw1( i, svar );		/* stosw */
		i = mov_save_movsw( i );		/* movsw */
		pghead[0] = 0;			/* page page head */
		pghead[1] = i;			/* dsize */
		pghead[2] = 0;			/* ox,oy */
		pghead[3] = 0;			/* wait & loop */
		pghead[4] = 0;			/* リザーブ */
		pghead[5] = 0;			/* sound data1 */
		pghead[6] = 0;			/* sound data2 */
		pghead[7] = 0;			/* sound data3 */
		for( j=0 ; j<6 ; j++ ){	/* disk write protect の場合6回必要 */ 
			if( (fps=fopen(namemov,"wb") ) != NULL )goto save0;
		}
		return 2;
	save0:	fwrite( (char *)mvhead1, 1, 28, fps );	/* ヘッダー */
		fwrite( (char *)mvhead2, 1, 228, fps );
		fwrite( (char *)pghead, 1, 32, fps );
		fwrite( bbuf, 1, i, fps );
		temp = ferror( fps );
		fclose( fps );
		svar[1] = i + 32;
		goto save10;
	}

	/* page > 0 */

	i = 0;				/* data counter */
	if( mode )WORD( bbuf+i ) = 3;	/* brock 数 */
	else WORD( bbuf+i ) = 2;
	if( svar[3] )WORD( bbuf+i ) += 1;
	i+=2;
	if( svar[3] )i = mov_save_movebox16( i, svar );
/*	if( svar[3] )i = mov_save_move_all_box_16( i, svar );	*/

	for( k=0 ; k<153600 ; k+=2 ){
		j = ( (k/640) << 10 ) + ( k % 640 );
		a1 = peekw( j, 0x104 ); a2 = DWORD( rbuf+k );
		if( mov_save_cmp_data( a1, a2, svar[2] ) == 0 
		 && (a2 & 0x8000) == 0 ){
			WORD( rbuf+k ) = a2 | 0x8000;	/* 処理印 */
			xorw( j, 0x104, 0xffff );
		}
	}
			/* 孤立した点は処理解除 */
	for( k=2 ; k<153598 ; k+=2 ){
		if( (DWORD( rbuf+k ) & 0x80008000) == 0x8000
		&& (WORD( rbuf+k-2 ) & 0x8000) == 0 ){
			WORD( rbuf+k ) &= 0x7fff;
			j = ( (k/640) << 10 ) + ( k % 640 );
			xorw( j, 0x104, 0xffff );
		}
	}

	if( mode )i = mov_save_stosw0( i, svar ); /* stosw 0type */
	i = mov_save_stosw1( i, svar );		/* stosw */
	i = mov_save_movsw( i );		/* movsw */
	pghead[0] = svar[0];		/* page page head */
	pghead[1] = i;			/* dsize */
	pghead[2] = 0;			/* ox,oy */
	pghead[3] = 0;			/* wait & loop */
	pghead[4] = 0;			/* リザーブ */
	pghead[5] = 0;			/* sound data1 */
	pghead[6] = 0;			/* sound data2 */
	pghead[7] = 0;			/* sound data3 */
	for( j=0 ; j<6 ; j++ ){	/* disk write protect の場合6回必要 */ 
		if( ( fps = fopen( namemov, "ab" ) ) != NULL )goto save2;
	}
	return 2;
save2:	fwrite( (char *)pghead, 1, 32, fps );
	fwrite( bbuf, 1, i, fps );
	temp = ferror( fps );
	fclose( fps );
	svar[1] = svar[1] + i + 32;
save10:	svar[0]++;
	if( temp ){
		remove( namemov );		/* disk full */
		return 2;
	}
	return 0;
}

/* store そのつどdataを読み込むtype */

mov_save_stosw0( i, svar )
int i;
int svar[];
{
	int p1, p4, p5, p6;
	int j, j2, j3;
	int k, k1;
	int a1, a2, data;
	int n2, n3;

	WORD( bbuf+i ) = 0x0222; i+=2;	/* stosw 0type brock */
	p1 = i; i+=4;			/* size point */
	p4 = i; i+=2;		/* offset count point */
	n2 = 0;			/* offset count */
	for( j2=0 ; j2<3 ; j2++ ){ /* offset loop */
	    p5 = i;			/* offset top point */
	    WORD( bbuf+i ) = j2; i+=2;	/* offset */
	    p6 = i; i+=2;		/* d-address count point */
	    n3 = 0;			/* d-address count */
	    k = 0; k1 = 0;		/* data長count係数 */
	    for( j3=0x10000*j2 ; j3<0x10000*(j2+1) ; j3+=2 ){
		if( j3 >= 153600 )break;
	 	j = ( (j3/640) << 10 ) + ( j3 % 640 );		/* vram add */
		a1 = peekw( j, 0x104 ); a2 = WORD( rbuf+j3 );
		if( k == 0 )data = a1;
		if( (a2 & 0x8000) == 0		 /* 手つかず */
		    && mov_save_cmp_data( data, a1, svar[2] ) == 0
		    				 /* 同色と認め */ 
		){
		    if( k == 0 )if(
		    		   mov_save_skip_check2(data,j3,svar)
		    		)goto stos01;
		    k++;
		    WORD( rbuf+j3 ) = 0x8000 | data;	/* 処理印 */
		    xorw( j, 0x104, 0xffff );
		    if( k == 1 ){
			n3++;
			WORD( bbuf+i ) = ( j3 & 0xffff );
		    }
		    if( k<0xff ){
			BYTE( bbuf+i+2 ) = k;
			WORD( bbuf+i+3 ) = data;
			k1 = 2+1+2;
		    }
		    if( (k>=0xff) && (k<0xffff) ){
			BYTE( bbuf+i+2 ) = 0xff;
			WORD( bbuf+i+3 ) = k;
			WORD( bbuf+i+5 ) = data;
			k1 = 2+3+2;
		    }
		    if( k>=0xffff ){
			BYTE( bbuf+i+2 ) = 0xff;
			WORD( bbuf+i+3 ) = 0xffff;
			DWORD( bbuf+i+5 ) = k;
			WORD( bbuf+i+9 ) = data;
			k1 = 2+7+2;
		    }
		}
		else {
		    if( k ){
			i = i + k1;
			k = 0; k1 = 0;
		    }
		}
	stos01: ;
	    }
	    i = i + k1;
	    WORD( bbuf+p6 ) = n3;
	    if( n3 )n2++;
	    else i = p5;

	}
	WORD( bbuf+p4 ) = n2;
	if( n2 == 0 )i = p4;
	DWORD( bbuf+p1 ) = i - p4;
	return i;
}

/* store 最初にdataを読み込むtype */

mov_save_stosw1( i, svar )
int i;
int svar[];
{
	int p1, p2, p3, p4, p5, p6;
	int j, j1, j2, j3;
	int k, k1;
	int data;
	int a1, a2;
	int n1, n2, n3;

	WORD( bbuf+i ) = 0x1222; i+=2;	/* stosw brock */
	p1 = i; i+=4;			/* size point */
	p2 = i; i+=2;			/* data count point */
	n1 = 0;				/* data count */
	for( j1=0 ; j1<153600 ; j1+=2 ){
	    if( WORD( rbuf+j1 ) & 0x8000 )goto stos03;	/* 処理済skip */
	    j = ( (j1/640) << 10 ) + ( j1 % 640 );	/* j = vram address */
	    data = peekw( j, 0x104 );
	    if(
	      mov_save_skip_check6( data, j1, svar )
	    )goto stos03;		/* skip check */
	    p3 = i;			/* data top point */
	    WORD( bbuf+i ) = data; i+=2;	/* data */
	    p4 = i; i+=2;		/* offset count point */
	    n2 = 0;			/* offset count */
	    for( j2=0 ; j2<3 ; j2++ ){ /* offset loop */
		p5 = i;			/* offset top point */
		WORD( bbuf+i ) = j2; i+=2;	/* offset */
		p6 = i; i+=2;		/* d-address count point */
		n3 = 0;			/* d-address count */
		k = 0; k1 = 0;		/* data長count係数 */
		for( j3=0x10000*j2 ; j3<0x10000*(j2+1) ; j3+=2 ){
		    if( j3 >= 153600 )break;
		    a2 = WORD( rbuf+j3 );
		    if( a2 & 0x8000 ){			/* 処理済skip */
			if( k ){
			    i = i + k1;
			    k = 0; k1 = 0;
			}
			goto stos01;
		    }
	 	    j = ( (j3/640) << 10 ) + ( j3 % 640 );
		    a1 = peekw( j, 0x104 );
		    if( (a2 & 0x8000) == 0		 /* 手つかず */
		        && mov_save_cmp_data( data, a1, svar[2] ) == 0 
		        				/* 同色と認め */ 
		    ){
			if( k == 0 )if( 
			  mov_save_skip_check4(data,j3,svar)
			)goto stos01;
			k++;
			WORD( rbuf+j3 ) = 0x8000 | data;	/* 処理印 */
			xorw( j, 0x104, 0xffff );
			if( k == 1 ){
			    n3++;
			    WORD( bbuf+i ) = ( j3 & 0xffff );
			}
			if( k<0xff ){
			    BYTE( bbuf+i+2 ) = k;
			    k1 = 1+2;
			}
			if( (k>=0xff) && (k<0xffff) ){
			    BYTE( bbuf+i+2 ) = 0xff;
			    WORD( bbuf+i+3 ) = k;
			    k1 = 3+2;
			}
			if( k>=0xffff ){
			    BYTE( bbuf+i+2 ) = 0xff;
			    WORD( bbuf+i+3 ) = 0xffff;
			    DWORD( bbuf+i+5 ) = k;
			    k1 = 7+2;
			}
		    }
		    else {
			if( k ){
			    i = i + k1;
			    k = 0; k1 = 0;
			}
		    }
	    stos01: ;
		}
	stos02:	i = i + k1;
		WORD( bbuf+p6 ) = n3;
		if( n3 )n2++;
		else i = p5;
	    }
	    WORD( bbuf+p4 ) = n2;
	    if( n2 )n1++;
	    else i = p3;
    stos03: ;
	}
	WORD( bbuf+p2 ) = n1;
	if( n1 == 0 )i = p2;
	DWORD( bbuf+p1 ) = i - p2;
	return i;
}

mov_save_skip_check2( data, n, svar )
int data, n;
int svar[];
{			/* 4つdataと同じ色が続くもの以外はスキップ */
	int a, b, i, j, k;

	if( n > 153588 )return 1;
	if( WORD( rbuf+n ) & 0x8000 )return 1;
	for( i=0 ; i<4 ; i++ ){
		k = n + (i << 1);
		j = ( (k/640) << 10 ) + ( k % 640 );
		a = peekw( j, 0x104 );
		b = WORD( rbuf + k );
		if( mov_save_cmp_data( data, a, svar[2]) )return 1;
	}
	return 0;
}

/* skip_check1 = 1:skip ( for stosw ) */

mov_save_skip_check4( data, n, svar )
int data, n;
int svar[];
{			/* 4つdataと同じ色が続くもの以外はスキップ */
	int a, b, i, j, k;

	if( n > 153588 )return 1;	/* ↓処理済直後はok */
	if( n && ( (DWORD( rbuf+n-2 ) & 0x80008000) == 0x8000 ) )return 0;
	if( WORD( rbuf+n ) & 0x8000 )return 1;
	for( i=0 ; i<4 ; i++ ){
		k = n + (i << 1);
		j = ( (k/640) << 10 ) + ( k % 640 );
		a = peekw( j, 0x104 );
		b = WORD( rbuf + k );
		if( b & 0x8000 )return 0;
		if( mov_save_cmp_data( data, a, svar[2]) )return 1;
	}
	return 0;
}

mov_save_skip_check6( data, n, svar )
int data, n;
int svar[];
{			/* 6つdataと同じ色が続くもの以外はスキップ */
	int a, b, i, j, k;

	if( n > 153588 )return 1;
	if( DWORD( rbuf+n ) & 0x80008000 )return 1;
	if( DWORD( rbuf+n+4 ) & 0x80008000 )return 1;
	if( DWORD( rbuf+n+8 ) & 0x80008000 )return 1;
	for( i=0 ; i<6 ; i++ ){
		k = n + (i << 1);
		j = ( (k/640) << 10 ) + ( k % 640 );
		a = peekw( j, 0x104 );
		b = WORD( rbuf + k );
		if( mov_save_cmp_data( data, a, svar[2]) )return 1;
	}
	return 0;
}

/* movsw */

mov_save_movsw( i )
int i;
{
	int p1, p4, p5, p6;
	int j, j2, j3, j4;
	int k, k1, k2;
	int a1, a2;
	int n2, n3;

	WORD( bbuf+i ) = 0x2222; i+=2;	/* movsw brock */
	p1 = i; i+=4;			/* size point */
	p4 = i; i+=2;		/* offset count point */
	n2 = 0;			/* offset count */
	for( j2=0 ; j2<3 ; j2++ ){ /* offset loop */
	    p5 = i;			/* offset top point */
	    WORD( bbuf+i ) = j2; i+=2;	/* offset */
	    p6 = i; i+=2;		/* d-address count point */
	    n3 = 0;			/* d-address count */
	    k = 0; k1 = 0;		/* data長count係数 */
	    for( j3=0x10000*j2 ; j3<0x10000*(j2+1) ; j3+=2 ){
		if( j3 >= 153600 )break;
	 	j = ( (j3/640) << 10 ) + ( j3 % 640 );		/* vram add */
		a1 = peekw( j, 0x104 ); a2 = WORD( rbuf+j3 );
		if( (a2 & 0x8000) == 0 ){
		    k++;
		    WORD( rbuf+j3 ) = 0x8000 | a1;		/* 処理印 */
		    xorw( j, 0x104, 0xffff );
		    if( k == 1 ){
			n3++;
			k2 = j3;			/* address記憶 */
			WORD( bbuf+i ) = ( j3 & 0xffff );
		    }
		    if( k<0xff ){
			BYTE( bbuf+i+2 ) = k;
			k1 = 1+2;
		    }
		    if( (k>=0xff) && (k<0xffff) ){
			BYTE( bbuf+i+2 ) = 0xff;
			WORD( bbuf+i+3 ) = k;
			k1 = 3+2;
		    }
		    if( k>=0xffff ){
			BYTE( bbuf+i+2 ) = 0xff;
			WORD( bbuf+i+3 ) = 0xffff;
			DWORD( bbuf+i+5 ) = k;
			k1 = 7+2;
		    }
		}
		else {
		    if( k ){
			i = i + k1;
			k = 0; k1 = 0;
			for( j4=k2 ; j4<j3 ; j4+=2 ){ /* data write */
			    WORD( bbuf+i ) = WORD( rbuf+j4 ) & 0x7fff;
			    i+=2;
			}
		    }
		}
	movs01: ;
	    }
    movs02: if( k ){
		i = i + k1;
		k = 0; k1 = 0;
		for( j4=k2 ; j4<j3 ; j4+=2 ){ /* data write */
		    WORD( bbuf+i ) = WORD( rbuf+j4 ) & 0x7fff;
		    i+=2;
		}
	    }
	    WORD( bbuf+p6 ) = n3;
	    if( n3 )n2++;
	    else i = p5;
 	}
	WORD( bbuf+p4 ) = n2;
	if( n2 == 0 )i = p4;
	DWORD( bbuf+p1 ) = i - p4;
	return i;
}

/* move all box ( 16*16dot )全域のboxを転送 */

mov_save_move_all_box_16( i, svar )
int i, svar[];
{
	int p1, p2;
	int j, j2, j3;
	int xmin, xmax, ymin, ymax, x, y, x1, y1, x2, y2, kx, ky;
	int max, a, a1, a2, b, r, g, cr, cb, yu, temp, temp2;
	int bfaddr, rbaddr, vraddr;
	char *offset1, *offset2;
	char vyuv[1024];		/* vram YUV data */

	offset1 = bbuf+0x1000;	/* 旧画面データをchar *offset1にもう1枚作る */
	for( j=0 ; j<153600 ; j+=4 )DWORD( offset1+j ) = DWORD( rbuf+j );
	offset2 = bbuf+0x30000;	/* 旧画面データのYUV data */
		/* rgb data (offset1) を yuv data (offset2) に */
	for( j=0 ; j<76800 ; j++ ){
		a = WORD( offset1 + (j << 1) );
		b = a & 0x1f;
		r = (a >> 5) & 0x1f;
		g = (a >> 10) & 0x1f;
			/* G,R,BをY,Cr,Cbに変換 */
		cr = -107*g + 128*r - 21*b + 3968;	/* 0〜256*31 */
		cb = -85*g - 43*r + 128*b + 3968;
		yu = ( 150*g + 77*r + 37*b ) >> 4;
			/* Cr(8), Cb(8), Y(16) */
		DWORD( offset2 +(j << 2) )
		 = (cr >> 5) + ((cb << 3)& 0x0ff00) + (yu << 16);
	}
	xmin = 16*( svar[4]/16 ); if( svar[4]%16 )xmin += 16;
	xmax = 16*( svar[6]/16 ); if( svar[6]%16 == 15 )xmax += 1;
	ymin = 16*( svar[5]/16 ); if( svar[5]%16 )ymin += 16;
	ymax = 16*( svar[7]/16 ); if( svar[7]%16 == 15 )ymax += 1;

	WORD( bbuf+i ) = 0x3110; i+=2;	/* move all box 16 */
	p1 = i; i+=4;			/* size point */
	p2 = i;
	for( y=0 ; y<240 ; y+=16 ){
	    for( x=0 ; x<320 ; x+=16 ){
			/* vram YUV */
		if( x < xmin || x >= xmax
		 || y < ymin || y >= ymax
		){
			kx = x;
			ky = y;
			goto mov01;
		}
		vraddr = y*1024 + x*2; 	/* vram address */
		j = 0;			/* count vyuv */
		for( j2=0 ; j2<16 ; j2++ ){
		    for( j3=0 ; j3<32 ; j3+=2 ){
			a = peekw( vraddr+j3, 0x104 );
			b = a & 0x1f;
			r = (a >> 5) & 0x1f;
			g = (a >> 10) & 0x1f;
				/* G,R,BをY,Cr,Cbに変換 */
			cr = -107*g + 128*r - 21*b + 3968;	/* 0〜256*31 */
			cb = -85*g - 43*r + 128*b + 3968;
			yu = ( 150*g + 77*r + 37*b ) >> 4;
				/* Cr(8), Cb(8), Y(16) */
			DWORD( vyuv +j )
			 = (cr >> 5) + ((cb << 3) & 0x0ff00) + (yu << 16);
			j+=4;
		    }
		    vraddr += 1024;
		}
		temp2 = mov_save_cmp_box16( offset2, x, y, vyuv, svar[2] );
		max = temp2;
		kx = x; ky = y;
		if( temp2 > 255-8 )goto mov01;
			/* 1dotづつずらして調べる */
		x1 = x - svar[3]; if( x1 < 0 )x1 = 0;
		x2 = x + svar[3]; if( x2 > 304 )x2 = 304;
		y1 = y - svar[3]; if( y1 < 0 )y1 = 0;
		y2 = y + svar[3]; if( y2 > 224 )y2 = 224;
		for( j2 = x1 ; j2 <= x2 ; j2++ ){
		    for( j3 = y1 ; j3 <= y2 ; j3++ ){
			temp
			= mov_save_cmp_box16( offset2, j2, j3, vyuv, svar[2] );
			if( temp > max ){
			    max = temp;
			    kx = j2; ky = j3;
			}
		    }
		}
			/* 大まかに調べる */
		x1 = x - 32; if( x1 < 0 )x1 = 0;
		x2 = x + 32; if( x2 > 304 )x2 = 304;
		y1 = y - 32; if( y1 < 0 )y1 = 0;
		y2 = y + 32; if( y2 > 224 )y2 = 224;
		for( j2 = x1 ; j2 <= x2 ; j2+=16 ){
		    for( j3 = y1 ; j3 <= y2 ; j3+=16 ){
			temp
			= mov_save_cmp_box16( offset2, j2, j3, vyuv, svar[2] );
			if( temp > max ){
			    max = temp;
			    kx = j2; ky = j3;
			}
		    }
		}
	mov01:	WORD( bbuf+i ) = kx; i+=2;
		WORD( bbuf+i ) = ky; i+=2;
		bfaddr = ky*640 + kx*2; 	/* offset1 相対 address */
		rbaddr = y*640 + x*2; 	/* rbuf 相対 address */
		vraddr = y*1024 + x*2; 	/* vram address */
		for( j2=0 ; j2<16 ; j2++ ){
			for( j3=0 ; j3<32 ; j3+=2 ){
			    a1 = peekw( vraddr+j3, 0x104 );
			    a2 = WORD( offset1+bfaddr+j3 ) & 0x7fff;
			    WORD( rbuf+rbaddr+j3 ) = a2;
			    if( (a1 & 0x8000) == 0 ){
			      if( mov_save_cmp_data( a1, a2, svar[2] )==0 ){
				WORD( rbuf+rbaddr+j3 ) = a2 | 0x8000;
				xorw( vraddr+j3, 0x104, 0xffff );
			      }
			    }
			    else WORD( rbuf+rbaddr+j3 ) = a2 | 0x8000;
			}
			bfaddr+=640; rbaddr+=640; vraddr+=1024;
		}
	    }
	}
	DWORD( bbuf+p1 ) = i - p2;
	return i;
}

/* move box ( 16*16dot )指定されたboxを転送 */

mov_save_movebox16( i, svar )
int i, svar[];
{
	int p1, p2, n;
	int j, j2, j3;
	int xmin, xmax, ymin, ymax, x, y, x1, y1, x2, y2, kx, ky;
	int max, a, a1, a2, b, r, g, cr, cb, yu, temp, temp2;
	int bfaddr, rbaddr, vraddr;
	char *offset1, *offset2;
	char vyuv[1024];		/* vram YUV data */

	offset1 = bbuf+0x1000;	/* 旧画面データをchar *offset1にもう1枚作る */
	for( j=0 ; j<153600 ; j+=4 )DWORD( offset1+j ) = DWORD( rbuf+j );
	offset2 = bbuf+0x30000;	/* 旧画面データのYUV data */
		/* rgb data (offset1) を yuv data (offset2) に */
	for( j=0 ; j<76800 ; j++ ){
		a = WORD( offset1 + (j << 1) );
		b = a & 0x1f;
		r = (a >> 5) & 0x1f;
		g = (a >> 10) & 0x1f;
			/* G,R,BをY,Cr,Cbに変換 */
		cr = -107*g + 128*r - 21*b + 3968;	/* 0〜256*31 */
		cb = -85*g - 43*r + 128*b + 3968;
		yu = ( 150*g + 77*r + 37*b ) >> 4;
			/* Cr(8), Cb(8), Y(16) */
		DWORD( offset2 +(j << 2) )
		 = (cr >> 5) + ((cb << 3)& 0x0ff00) + (yu << 16);
	}

	WORD( bbuf+i ) = 0x3010; i+=2;	/* move box 16 */
	p1 = i; i+=4;			/* size point */
	p2 = i; i+=2;		/* data 個数 count point */
	n = 0;			/* data 個数 count */
		/* trimming area を はずすためのもの */
	xmin = 16*( svar[4]/16 ); if( svar[4]%16 )xmin += 16;
	xmax = 16*( svar[6]/16 ); if( svar[6]%16 == 15 )xmax += 1;
	ymin = 16*( svar[5]/16 ); if( svar[5]%16 )ymin += 16;
	ymax = 16*( svar[7]/16 ); if( svar[7]%16 == 15 )ymax += 1;
	for( y=ymin ; y<ymax ; y+=16 ){
	    for( x=xmin ; x<xmax ; x+=16 ){
			/* vram YUV */
		vraddr = y*1024 + x*2; 	/* vram address */
		j = 0;			/* count vyuv */
		for( j2=0 ; j2<16 ; j2++ ){
		    for( j3=0 ; j3<32 ; j3+=2 ){
			a = peekw( vraddr+j3, 0x104 );
			b = a & 0x1f;
			r = (a >> 5) & 0x1f;
			g = (a >> 10) & 0x1f;
				/* G,R,BをY,Cr,Cbに変換 */
			cr = -107*g + 128*r - 21*b + 3968;	/* 0〜256*31 */
			cb = -85*g - 43*r + 128*b + 3968;
			yu = ( 150*g + 77*r + 37*b ) >> 4;
				/* Cr(8), Cb(8), Y(16) */
			DWORD( vyuv +j )
			 = (cr >> 5) + ((cb << 3) & 0x0ff00) + (yu << 16);
			j+=4;
		    }
		    vraddr += 1024;
		}
		temp2 = mov_save_cmp_box16( offset2, x, y, vyuv, svar[2] );
		if( temp2 > 255-8 )goto mov02;
		max = temp2;
		kx = x; ky = y;
			/* 1dotづつずらして調べる */
		x1 = x - svar[3]; if( x1 < 0 )x1 = 0;
		x2 = x + svar[3]; if( x2 > 304 )x2 = 304;
		y1 = y - svar[3]; if( y1 < 0 )y1 = 0;
		y2 = y + svar[3]; if( y2 > 224 )y2 = 224;
		for( j2 = x1 ; j2 <= x2 ; j2++ ){
		    for( j3 = y1 ; j3 <= y2 ; j3++ ){
			temp
			= mov_save_cmp_box16( offset2, j2, j3, vyuv, svar[2] );
			if( temp > max ){
			    max = temp;
			    kx = j2; ky = j3;
			}
		    }
		}
			/* 大まかに調べる */
		x1 = x - 32; if( x1 < 0 )x1 = 0;
		x2 = x + 32; if( x2 > 304 )x2 = 304;
		y1 = y - 32; if( y1 < 0 )y1 = 0;
		y2 = y + 32; if( y2 > 224 )y2 = 224;
		for( j2 = x1 ; j2 <= x2 ; j2+=16 ){
		    for( j3 = y1 ; j3 <= y2 ; j3+=16 ){
			temp
			= mov_save_cmp_box16( offset2, j2, j3, vyuv, svar[2] );
			if( temp > max ){
			    max = temp;
			    kx = j2; ky = j3;
			}
		    }
		}
		if( max > temp2+8 ){
		    DWORD( bbuf+i ) = y*640 + x*2; i+=4;
		    WORD( bbuf+i ) = kx; i+=2;
		    WORD( bbuf+i ) = ky; i+=2;
		    n++;
		    bfaddr = ky*640 + kx*2; 	/* offset1 相対 address */
		    rbaddr = y*640 + x*2; 	/* rbuf 相対 address */
		    vraddr = y*1024 + x*2; 	/* vram address */
		    for( j2=0 ; j2<16 ; j2++ ){
			for( j3=0 ; j3<32 ; j3+=2 ){
			    a1 = peekw( vraddr+j3, 0x104 );
			    a2 = WORD( offset1+bfaddr+j3 ) & 0x7fff;
			    WORD( rbuf+rbaddr+j3 ) = a2;
			    if( mov_save_cmp_data( a1, a2, svar[2] ) == 0 
		 	    && (a1 & 0x8000) == 0 ){
				WORD( rbuf+rbaddr+j3 ) = a2 | 0x8000;
				xorw( vraddr+j3, 0x104, 0xffff );
			    }
			}
			bfaddr+=640; rbaddr+=640; vraddr+=1024;
		    }
	    mov02:  ;
		}
	    }
	}
	WORD( bbuf+p2 ) = n;
	if( n == 0 )i = p2;
	DWORD( bbuf+p1 ) = i - p2;
	return i;
}

/* YUV data buffer の char buffer(320*240)[開始座標(x,y)]と
char *vyuv(16*16)の中でYUV判定で同じものを数える */

mov_save_cmp_box16( buffer, x, y, vyuv, rate )
char *buffer, *vyuv;
int x, y, rate;
{
	int d1, d2, i, j, n, rate2;

	buffer = buffer + 1280*y + 4*x;
	n = 0; rate2 = rate*rate;
	for( j=0 ; j<16 ; j++ ){
		for( i=0 ; i<64 ; i+=4 ){
		    d1 = (WORD( buffer+i+2 ) - WORD( vyuv+2 ));
		    if( d1 > rate )goto cmp01;
		    if( d1 < -rate )goto cmp01;
		    d1 = BYTE( buffer+i ) - BYTE( vyuv );
		    d2 = BYTE( buffer+i+1 ) - BYTE( vyuv+1 );
		    if( d1*d1 + d2*d2 <= rate2 )n++;
	    cmp01:  vyuv += 4;
		}
		buffer += 1280;
	}
	return n;
}

/* Y,Cr,CbによるCOLCOR DATA比較法 91 7 24 */

mov_save_cmp_data( a, b, rate )
int a, b, rate;
{
	int b1,r1,g1, b2,r2,g2, d1, d2;

	if( (a & 0x7fff) == (b & 0x7fff) )return 0; /* 明白なものは処理 */
	else if( rate == 0 )return 1;
		/* G,R,B算出 */
	b1 = a & 0x1f; b2 = b & 0x1f;
	r1 = (a >> 5) & 0x1f; r2 = (b >> 5) & 0x1f;
	g1 = (a >> 10) & 0x1f; g2 = (b >> 10) & 0x1f;
		/* G,R,BをY,Cr,Cbに変換 & 判定 */
	d1 = ( 150*(g2 - g1) + 77*(r2 - r1) + 37*(b2 - b1) ) >> 4;
	if( d1 > rate )return 1;
	if( d1 < -rate )return 1;
	d1 = ( -107*(g2-g1) + 128*(r2-r1) - 21*(b2-b1) ) >> 5;
	d2 = ( -85*(g2 -g1) - 43*(r2 -r1) + 128*(b2 -b1) ) >> 5;
	if( d1*d1 + d2*d2 > rate*rate )return 1;
	else return 0;
}

