/*
		TPSC256用 外部Shell
		
		パレットをソ−トする
		使っている色を前に､使っていない色を後ろにソ−トする
		
*/

#define EGBSIZE		1536	// EGB用ワ−クサイズ
#define MOSSIZE		4096	// マウス用ワ−クサイズ
#define BOOL		int		// 論理判断の型宣言
#define TRUE		1		// 真
#define FALSE		0		// 偽
#define MENUPAGE	0		// メニュ−ペ−ジ番号
#define DRAWPAGE	0		// 描画ペ−ジ番号
#define SCREEN		12		// 画面モ−ド
#define DRAWWIDE	640		// 処理画面横サイズ
#define DRAWHIDE	480		// 処理画面縦サイズ


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <egb.h>
#include <mos.h>
#include <loader.h>			// コプロセス定義ファイル

char EGB_work[EGBSIZE];		// EGBワ−クエリア
char MOS_work[MOSSIZE];		// マウスワ−クエリア

BOOL flg[256];

void GetPaltte( pal_all )
char *pal_all;
{
	EGB_getPalette(DRAWPAGE,pal_all);
}

void SetPaltte( pal_all )
char *pal_all;
{
	EGB_palette(EGB_work,1,pal_all);
}

void GetBlock(x1,y1,x2,y2,p)
int x1,y1,x2,y2;
unsigned int p;
{
	struct {
		unsigned int	p ;
		short	dseg, x1, y1, x2, y2 ;
	} pgetput ;
	pgetput.p    = p ;
	pgetput.dseg = getds();
	pgetput.x1   = x1 ;		pgetput.y1   = y1 ;
	pgetput.x2   = x2 ;		pgetput.y2   = y2 ;
	EGB_getBlock(EGB_work,(char *)&pgetput);
}

void PutBlock( x1,y1,x2,y2,p )
int x1,y1,x2,y2;
unsigned int p;
{
	struct {
		unsigned int	p ;
		short	dseg, x1, y1, x2, y2 ;
	} pgetput ;
	pgetput.p    = p ;
	pgetput.dseg = getds();
	pgetput.x1   = x1 ;		pgetput.y1   = y1 ;
	pgetput.x2   = x2 ;		pgetput.y2   = y2 ;
	EGB_putBlock(EGB_work,0,(char *)&pgetput);
}

void Line(x1,y1,x2,y2)
int x1,y1,x2,y2;
{
struct { 	unsigned short int n;
			short int x1,y1,x2,y2; } par;
	par.n = 2;
	par.x1 = x1; par.y1 = y1;
	par.x2 = x2; par.y2 = y2;
	EGB_connect(EGB_work,(char *)&par);
}

void ColorFind()
{
	int x,y;
	int col;
	char *buf;
	
	buf = malloc( DRAWWIDE );
	for(y=0;y<DRAWHIDE;y++) {
		GetBlock(0,y,DRAWWIDE-1,y,buf);
		EGB_writeMode(EGB_work,4);
		Line(0,y,DRAWWIDE-1,y);
		for(x=0;x<DRAWWIDE;x++) {
			col = buf[x];
			flg[col] = TRUE;
		}
		Line(0,y,DRAWWIDE-1,y);
		EGB_writeMode(EGB_work,0);
	}
	free( buf );
}

void PaltteSort()
{
	int ch,mx,my;
	int x,y;
	int i,j;
	int ary[256];
	int col;
	char *oldpalt,*newpalt;
	char *buf;
	
	ary[0] = 0;
	ary[255] = 255;
	j = 1;
	for(i=1;i<255;i++) {
		if( flg[i] == TRUE ) {
			ary[i] = j;
			j++;
		}
	}
	for(i=1;i<255;i++) {
		if( flg[i] != TRUE ) {
			ary[i] = j;
			j++;
		}
	}
	oldpalt= malloc( 256*8+4 );
	newpalt= malloc( 256*8+4 );
	GetPaltte(oldpalt);
	memcpy(newpalt,oldpalt,256*8+4);
	for(i=0;i<256;i++) {
		j = ary[i];
		newpalt[j*8  +4+4] = oldpalt[i*8  +4+4];
		newpalt[j*8+1+4+4] = oldpalt[i*8+1+4+4];
		newpalt[j*8+2+4+4] = oldpalt[i*8+2+4+4];
	}
	buf = (char *)malloc( DRAWWIDE*DRAWHIDE );
	if( buf == NULL ) {
		SetPaltte(newpalt);
		buf = (char *)malloc( DRAWWIDE );
		for(y=0;y<DRAWHIDE;y++) {
			MOS_rdpos(&ch,&mx,&my);
			if( ch != 0 ) break;
			GetBlock(0,y,DRAWWIDE-1,y,buf);
			for(x=0;x<DRAWWIDE;x++) {
				col = buf[x];
				buf[x] = ary[col];
			}
			PutBlock(0,y,DRAWWIDE-1,y,buf);
		}
	} else {
		GetBlock(0,0,DRAWWIDE-1,DRAWHIDE-1,buf);
		for(x=0;x<DRAWWIDE*DRAWHIDE;x++) {
			col = buf[x];
			buf[x] = ary[col];
		}
		SetPaltte(newpalt);
		PutBlock(0,0,DRAWWIDE-1,DRAWHIDE-1,buf);
	}
	free( oldpalt );
	free( newpalt );
	free( buf );
}

main()
{
	ADDRESS temp;
	int i,x,y;
	int page[2];
	
	pcl_get_dta(&temp);
	
	/* 画面･マウスの初期化 */
	EGB_getResolution(&page[0], &page[1]);
	if( page[0] != SCREEN ) goto quit;
	
	EGB_resolution(EGB_work,DRAWPAGE,page[0]|0x40);		// Page0 Init
	EGB_displayPage(EGB_work,0,1);						// 1page view
	MOS_start(MOS_work,MOSSIZE);						// マウス初期化
	MOS_resolution(DRAWPAGE,page[0]);
	
	EGB_writePage(EGB_work,DRAWPAGE);	// 描画ペ−ジを指定
	EGB_paintMode(EGB_work,0x22);		// ペイントモ−ドを指定
	EGB_color(EGB_work,0,255);			// ドットの色を指定
	EGB_writeMode(EGB_work,0);
	
	for(i=0;i<256;i++)
		flg[i] = FALSE;				// フラグの初期化
	
	/* 処理開始 */
	ColorFind();
	PaltteSort();
	
	/* 子プロセスの終了処理 */
	MOS_end();

quit:
	pcl_exit(0);
	return (0);
}
