/** << MSC V5.1 >> ************************************************************
**
**	パレット変更 ( FMTOWNS 16 色モード ）その２
**
**	< Parameter >
**	BC2  <BRG>  [Palno.]
**		 BRG    : <Blue><Red><Green>
**		          0 〜 F (HEX) で輝度を指定する｡
**		 Palno. : ﾊﾟﾚｯﾄ番号 ( 0 〜 F (HEX) )
**		          省略値は、0 (背景色のﾊﾟﾚｯﾄ番号)
**
**	< HISTORY >
**	1989.10.07 : CREATE
**	1990.04.16 : FMRに対応
**	1990.05.14 : 変更する色指定を1,2,3の他にB,R,Gでも可にした。
**	1990.11.30 : 新型FMTOWNSに対応
**
**	All Rights Reserved, Copyright (C) Y.Hirata 1990.
**
**	Programmed by Y.Hirata ( Nifty ID : NAB03321 )
**
******************************************************************************/
#include	<stdio.h>
#include	<dos.h>
#include	<conio.h>
#include	<stdlib.h>

#define		VER_LEV		(1.20)

/*		FMTOWNS				*/
#define		PALETTE		0xfd90
#define		BLUE		0xfd92
#define		RED			0xfd94
#define		GREEN		0xfd96
/*		FMR					*/
#define		CONTROL		0x0400
#define		R_PALETTE	0x0408
#define		R_BLUE		0x040a
#define		R_RED		0x040c
#define		R_GREEN		0x040e

unsigned int	Palette ;
unsigned int	Blue ;
unsigned int	Red ;
unsigned int	Green ;

char	*Msg[12] = {
					"(C)パオパオ  ﾊﾟﾚｯﾄ色変更ﾌﾟﾛｸﾞﾗﾑ(2)  Version ",
					"Copyright (C) Y.Hirata 1989-1990. All rights reserved.",
					"BC2  <BRG>  [Palno.]",
					"     BRG    : <Blue><Red><Green>",
					"              0 〜 F (HEX) で輝度を指定する｡",
					"     Palno. : ﾊﾟﾚｯﾄ番号 ( 0 〜 F (HEX) )",
					"              省略値は、0 (背景色のﾊﾟﾚｯﾄ番号)",
					"操作 : 1,2,3 で変更色を設定、↑,↓ で色調整、ESCｷｰで終了",
					"       1:Blue, 2:Red, 3:Green, ↑:Up, ↓:Down",
					"       1,2,3 の代わりに B,R,G でも可能！",
					"参考 : GETBC にて設定した色を数値で確認できます。",
					"FMR-60では、最後に /r を指定して下さい｡"
					} ;

#define		TRUE	1
#define		FALSE	0

/*******************************  GET Machine ID  ****************************/
/*
**	< RETURN >
**	 機種識別 :
**				Towns1,2      = 1
**				Towns1,2(F,H) = 2 ('90秋型を含む)
**				R70           = 3
**				R60/50        = 4
**				R50S          = 5
**				R50LT         = 6
**				???           = 0
*/
int mid()
{
	union	REGS	regs ;
	struct	SREGS	sregs ;
	unsigned char	mdata[16] ;
	unsigned char	id, cpu ;
	
	regs.h.ah = 0x05 ;
	regs.x.di = (unsigned int)mdata ;

	segread( &sregs ) ;
	int86x( 0xaf,&regs,&regs,&sregs ) ;

	id = mdata[0] ;
	if ( (id & 0x07) == 0x01 ) {				/*  R60/50 系列	*/
		if ( (id & 0xf0) == 0x50 ) {			/*  FMTowns		*/
			cpu = inp( 0x31 ) ;
			switch ( cpu ) {
				case 1 :
						return ( 1 ) ;			/*  ﾓﾃﾞﾙ 1,2	*/
						break ;
				case 2 :
						return ( 2 ) ;			/*  ﾓﾃﾞﾙ 1,2(F,H)	*/
						break ;
				default :
						return ( 2 ) ;			/*  ?????		*/
/*
**	新型FMTOWNSは、これでいいと思う｡
*/
						break ;
			}
		} else if ( (id & 0xf0) == 0x20 ) {		/*  R-70		*/
			return ( 3 ) ;
		} else if ( (id & 0xf0) == 0x00 ) {		/*  R-60/50		*/
			return ( 4 ) ;
		} else if ( (id & 0xf0) == 0x30) {		/*  R-50S		*/
			return ( 5 ) ;
		} else if ( (id & 0xf0) == 0x40) {		/*  R-50LT		*/
			return ( 6 ) ;
		} else {								/*  ?????		*/
			return ( 0 ) ;
		}
	} else {									/*  ?????		*/
		return ( 0 ) ;
	}
}

/************************  char 0-f(F) -> int 0-15  **************************/
int ctoi( c )
char	c ;
{
	int	i=0 ;

	if ( c >= '0' && c <= '9' ) {
		i = c - '0' ;
	} else {
		if ( c >= 'A' && c <= 'F' )
			i = 10 + c - 'A' ;
		if ( c >= 'a' && c <= 'f' )
			i = 10 + c - 'a' ;
	}
	return i ;
}

/*****************************  入力キーのチェック  **************************/
int keychk()
{
	union	REGS	inregs,outregs ;
	struct	SREGS	segregs ;

	int	int86x() ;
	int on ;

	on = 0 ;
	inregs.h.ah = 0x09 ;
	inregs.h.al = 0 ;

	int86x( 0x90,&inregs,&outregs,&segregs ) ;
											/* 1 2 3 ↑ ↓ キー on?	*/
	/* 1:b 2:r 3:g ↑ ↓ キー on?	*/
	if ( outregs.h.bh == 0x02 || outregs.h.bh == 0x2e )	/* 1 or B	*/
		on = 1 ;
	if ( outregs.h.bh == 0x03 || outregs.h.bh == 0x14 )	/* 2 or R	*/
		on = 2 ;
	if ( outregs.h.bh == 0x04 || outregs.h.bh == 0x22 )	/* 3 or G	*/
		on = 3 ;
	if ( outregs.h.bh == 0x4d )				/* ↑	*/
		on = 4 ;
	if ( outregs.h.bh == 0x50 )				/* ↓	*/
		on = 5 ;
	if ( outregs.h.bh == 0x01 )				/* ESC	*/
		on = 6 ;

	return on ;
}

/****************************  パレット色設定  *******************************/
void outiop( b, r, g )
int	b,r,g ;
{
	if ( b < 0 )  b = 0 ;
	if ( b > 15 ) b = 15 ;
	if ( r < 0 )  r = 0 ;
	if ( r > 15 ) r = 15 ;
	if ( g < 0 )  g = 0 ;
	if ( g > 15 ) g = 15 ;
	outp( Blue ,b*16 ) ;				/* 上位 8 bit にセット	*/
	outp( Red  ,r*16 ) ;
	outp( Green,g*16 ) ;
}

/*****************************  ★ メイン ★  ********************************/
main( int ac, char *av[] )
{
	int	ctoi(), keychk() ;
	int	p, b, r, g ;
	int	esc=1, key, sel ;
	int	c, cc, arglen ;
	int	id ;
	int	r60 = FALSE ;

	if ( ac > 1 ) {
		for ( c=1; c<ac; c++ ) {
			if ( *av[c] == '-' || *av[c] == '/' ) {		/* ｵﾌﾟｼｮﾝｽｲｯﾁ	*/
				arglen = strlen( av[c] ) ;
				for ( cc=1; cc<arglen; cc++ ) {
					switch ( *(av[c]+cc) ) {
						case 'r' :
						case 'R' :
							r60 = TRUE ;
							break ;
						default :
							printf("\x1b[1;33m") ;
							printf("Option switch error(%c)",*(av[c]+cc)) ;
							printf("\x1b[m\n") ;
							break ;
					}
				}
			}
		}
	}
	id = mid() ;
	switch ( id ) {							/*  機種判別	*/
		case 1 :							/*  FMTOWNS		*/
		case 2 :							/*  FMTOWNS		*/
		case 5 :							/*  FMR-50S		*/
				Palette = PALETTE ;
				Blue = BLUE ;
				Red = RED ;
				Green = GREEN ;
				break ;
		case 4 :							/*  FMR-60/50	*/
				Palette = PALETTE ;
				Blue = BLUE ;
				Red = RED ;
				Green = GREEN ;
				if ( !r60 ) {
					break ;
				}
		case 3 :							/*  FMR-70		*/
				outp( CONTROL ,0x05 ) ;
				Palette = R_PALETTE ;
				Blue = R_BLUE ;
				Red = R_RED ;
				Green = R_GREEN ;
				break ;
		case 6 :							/*  FMR-50LT	*/
		default :							/*  ?????		*/
				printf("\nこのマシンでは、使用できません！\n") ;
				exit ( 1 ) ;
				break ;
	}
	if ( ac < 2 ) {								/*  引数なし	*/
		printf("%s%04.2f\n",Msg[0],VER_LEV) ;
		printf("%s\n",Msg[1]) ;
		printf("\n") ;
		for ( c=2; c<11; c++ ) {
			printf("%s\n",Msg[c]) ;
		}
		if ( id == 4 ) {
			printf("%s\n",Msg[11]) ;
		}
	} else {									/*  引数あり	*/
		p = 0 ;
		if ( ac > 2 )
			p = ctoi( *av[2] ) ;
		outp( Palette,p ) ;
		b = ctoi( *av[1] ) ;
		r = ctoi( *(av[1]+1) ) ;
		g = ctoi( *(av[1]+2) ) ;
		outiop( b,r,g ) ;
		key = keychk() ;
		if ( key == 0 || key == 6 ) {
			esc = 0 ;
			outiop( b,r,g ) ;
		}
		sel = 0 ;
		if ( key >= 1 && key <= 3 )
			sel = key ;

		while ( esc ) {
			key = keychk() ;
			switch ( key ) {
				case 1 :
				case 2 :
				case 3 :
					sel = key ;
					break ;
				case 4 :
					switch ( sel ) {
					case 1 :
						outiop( ++b,r,g ) ;
						break ;
					case 2 :
						outiop( b,++r,g ) ;
						break ;
					case 3 :
						outiop( b,r,++g ) ;
						break ;
					}
					break ;
				case 5 :
					switch ( sel ) {
					case 1 :
						outiop( --b,r,g ) ;
						break ;
					case 2 :
						outiop( b,--r,g ) ;
						break ;
					case 3 :
						outiop( b,r,--g ) ;
						break ;
					}
					break ;
				case 6 :
						esc = 0 ;
						break ;
			}
		}	/* while	*/

	}
}

