/*********************************************************************

		   MSX SCREEN12 BSAVE FILE -> MSX SCREEN8 BSAVE FILE
   		     by ちにゃと    (NIFTY-Serve ID:GFH01000)

		            1993/12/07       Ver 2.1 L20            

********************************************************************/

                     
#include <io.h>
#include <fcntl.h>
#include <stat.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <mos.h>
#include <math.h>
#include <stat.h>


/* T-BIOS C ﾗｲﾌﾞﾗﾘ ﾍｯﾀﾞｰ */
#include <fmcfrb.h>
char fname[256];
char filepath[256];
char sccext[10];
char srsext[10];
char scchead[10];
char sccdata[256*64][4];
char sc8data[256*64][4];
char wildfname[100][256];
unsigned char r[4];
unsigned char g[4];
unsigned char b[4];
int bb[4];
unsigned char y[4];
unsigned char k,kj;
int rshift,gshift,bshift;
int sccsize;
int i,j,wildcard;
int w_ret;
int mode;
int fileno;
int namelen;
int flong;
int findflag;
int wildct;
int sc8tmp;
static struct find_t wildfbuf;
static unsigned long ret,pan;
int x;
/************************************************************
【オプション解析】

		概要	ｵﾌﾟｼｮﾝﾊﾟﾗﾒ-ﾀの解析を行い結果を返す
		用法	optionset( argc, *argv[] );
		引数	int		argc
				char	*argv[]
		戻り値 	int		0	正常終了
						-1	ｵﾌﾟｼｮﾝの指定が正しくない
************************************************************/

int optionset( int argc, char *argv[] ){

	int		count;
	char	c;
	ret=0;

	strcpy(sccext,"SCC");
	strcpy(srsext,"SRS");
	rshift=2;
	gshift=2;
	bshift=4;	
	ret = 0;
	findflag=0;
	/* ｵﾌﾟｼｮﾝ ﾊﾟﾗﾒｰﾀ 解析 */
	if ( argc == 1 ) {
		ret=-1;
	} 
	else{
		for ( count = 1; count < argc; count++ ){
            c = *argv[count];                        /* 先頭文字 get */
            if ( c == '/' || c == '-' ){
                c = *(argv[count] + 1);                /* 2 文字目 get */
                switch ( c ){
                    case 'h':
                    case 'H':
                    case '?':
                        ret = -1;
                        break;

                    case 'r':
                    case 'R':
    	                rshift = *(argv[count] + 2);
                        rshift -= 0x30; 
                        break;

                    case 'g':
                    case 'G':
    	                gshift = *(argv[count] + 2);
                        gshift-=0x30;
                        break;

                    case 'b':
                    case 'B':
    	                bshift = *(argv[count] + 2);
                        bshift-=0x30;
                        break;

  	                /* 無効 ﾊﾟﾗﾒｰﾀ */
    	            default:
                    ret = -1;
                }		/* <switch> */
            }
            else{
               	strcpy(fname, argv[count] );
         	}
        }	/* <for> */
  	}
	if(ret==-1){
		printf("****************************************************\n");
		printf("   MSX SCREEN12 BSAVE FILE -> SCREEN8 BSAVE FILE\n");
		printf("        by ちにゃと    (NIFTY-Serve ID:GFH01000)\n");
		printf("            1993/12/07       Ver 2.1 L20        \n");
		printf("****************************************************\n");
		printf("\n");
		printf("用法) RUN386  SCC2SC8.EXP [-Rx] [-Gx] [-Bx] FILENAME\n");
		printf("\n");
		printf("-Rx -Gx -Bx   RGBの強さを調整  x=0,1,2,3,4 \n");
		printf("              省略時は -R2 -G2 -B4\n");
		printf("              (B のみ他の 2倍で指定)\n");
		printf("\n");
		printf("FILENAME      拡張子が .SCC .SRS  のみ\n");
		printf("              ワイルドカ−ドも指定可能\n");
		printf("\n");
		printf("ex1)  RUN386 SCC2SC8.EXP SAMPLE.SCC\n");
		printf("ex2)  RUN386 SCC2SC8.EXP A:*.SCC\n");
		printf("ex3)  RUN386 SCC2SC8.EXP A:\\SCC\\SAMPLE*.SCC\n");
		printf("\n");
		printf("\n");
		printf("\n");
		return(-1);
	}
	namelen=strlen(fname);
	flong=namelen;
	for ( i =namelen-1; (i+1)>0 ;i-- ){
		fname[i]=toupper(fname[i]);
	}
	for ( i =namelen-1; (i+1)>0 ;i-- ){
		if ( fname[i] != 0x5c ){
			flong -= 1;
		}
		else {
			findflag=1;
			break;
		}
	}
	if(findflag==0){
		flong=1;
		for ( i = 0; i <255 ;i ++ ){
			if ( fname[i] != 0x3a ){
				flong += 1;
			}
			else {
				findflag=2;
				break;
			}
		}
	}
	if(findflag!=0){
		strncpy( filepath,fname,flong );
	}
	flong =strlen(fname);
	for (i=0;i<3;i++){
		if(fname[flong-3+i]!=sccext[i]&&fname[flong-3+i]!=(sccext[i]+0x20)&&
		   fname[flong-3+i]!=srsext[i]&&fname[flong-3+i]!=(srsext[i]+0x20) )
		{
			printf("拡張子が .SCC でも .SRS でもありません｡\n");
			return(-1);
		}
	}
	return ret;
}
/************************************************************

						sccload

************************************************************/
int sccload()

{
char fname2[256];

strcpy(fname2,fname);
printf("%s   ",fname);


	if (_access(fname2,0) !=0 ){
		printf("no scc file");
		return(-1);
	}
	else{
		pan=_open(fname2,_O_BINARY | _O_RDWR );
		if (pan== -1 ){
			return(-1);
		}
		ret=_read(pan,scchead,7);
		if (ret== -1){
			_close(pan);
			return(-1);
		}
		else{
			if(scchead[0]!=0xfe){
				printf("BSAVE FORMATではありません｡\n");
				_close(pan);
				return(-1);
			}
			sccsize=scchead[4]*256+scchead[3]+1;
			for( ; ; ){
				ret = _read(pan,&sccdata[0][0],256*256);
				if (ret == -1 ){
					_close(pan);
					printf("読み込みエラ−が発生しました。\n");
					return(-1);
				}
				else{
					_close(pan);
					break;
				}
			}
		}
	}
	return(0);
}
/***************************************************************
【ﾃﾞ-ﾀﾌｧｲﾙを作成する】

		概要	
		用法	sc8save();
		引数	無し
***************************************************************/

int sc8save ( void )
{
	char fname2[256];
	int		wsize;
	flong = 0;

	for ( i = 0; i <251 ;i ++ ){
		if ( fname[i] != 0x2e ){
			flong += 1;
		}
		else {
			break;
		}
	}
	strncpy( fname2,fname,flong );
	fname2[flong]=0x00;
	strcat( fname2,".SC8");
	fname2[flong+4]=0x00;



	if ( _access( fname2, 0 ) == 0 ) {
/*		printf( " 同名のファイルがあります。上書きします。 " );
*/		ret = _unlink ( fname2 );
	}
	ret = 0;
	pan = _open( fname2,_O_BINARY | _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE );
	if ( pan == -1) {
		printf(" 書き込みのオ−プンに失敗しました。\n" );
		ret = -1;
	}
	if ( ret == 0 ) {
		wsize = _write( pan, &scchead[0], 7  );
		if ( wsize == -1 || wsize != 7 ) {
			printf(" ヘッダ書き込みに失敗しました。\n" );
			_close( pan );
			return(-1);
		}
		else{
			wsize = _write( pan, &sc8data[0][0], sccsize  );
			if ( wsize == -1 || wsize != ( sccsize ) ) {
				printf(" デ−タ書き込みに失敗しました。\n" );
				_close( pan );
				return(-1);
			}
			else{
				printf("\n");
			}
		}
	}
	return (0);
}


/*********************************************************

			  			convert
			  			
*********************************************************/
int convert(){
	x=0;
	for(i=0;i<sccsize/4;i++){
		y[0]=sccdata[i][0] / 8;
		y[1]=sccdata[i][1] / 8;
		y[2]=sccdata[i][2] / 8;
		y[3]=sccdata[i][3] / 8;
		k = ( sccdata[i][0] & 7 )+ (sccdata[i][1] & 3 )*8;
		kj= ( sccdata[i][2] & 7 )+ (sccdata[i][3] & 3 )*8;
/*		if(x==256*127){
		printf("y0=%3d y1=%3d y2=%3d y3=%3d k=%3d j=%3d\n"
				,y[0],y[1],y[2],y[3],k,kj);
		}
*/		for(j=0;j<4;j++){
			bb[j]=y[j];
			r[j]=y[j];
			g[j]=y[j];
			b[j]=y[j];
			if((sccdata[i][1] & 4 )==0){
				g[j]+=k;
				bb[j]-=k;
			}
			else{
				if(g[j]>=(32-k) ){
					g[j]-=(32-k);
				}
				else{
					g[j]=0;
				}
				bb[j]+=(32-k);
			}
			if((sccdata[i][3] & 4 )==0){
				r[j]+=kj;
				bb[j]-=(kj*2);
			}
			else{
				if(r[j]>=(32-kj)){
					r[j]-=(32-kj);
				}
				else{
					r[j]=0;
				}
				bb[j]+=((32-kj)*2);
			}
/*			if(x==256*127){
			printf("r=%3d g=%3d b=%3d bb=%3d   ",r[j],g[j],b[j],bb[j]);
			}
*/			if( bb[j] >= 0 ){
				b[j]+=(bb[j]/4);
			}
			else{
				if( b[j] > (-1)*((bb[j]+2)/4) ){
/*				if(x==256*127){printf("root2\n");}
*/					b[j]+=(bb[j]/4);
				}
				else{
/*				if(x==256*127){printf("root3\n");}
*/					b[j]=0;
				}
			}
/*			if(x==256*127){
				printf("r=%3d g=%3d b=%3d bb=%3d\n",r[j],g[j],b[j],bb[j]);
			}
*/			if (r[j]>31){
				r[j]=31;
			}
			if (g[j]>31){
				g[j]=31;
			}
			if (b[j]>31){
				b[j]=31;
			}
			r[j]=(r[j]+rshift)/4;
			g[j]=(g[j]+gshift)/4;
			b[j]=(b[j]+bshift)/8;	
			if ((r[j] & 0x80)!=0){
				r[j]=0;
			}
			if ((g[j] & 0x80)!=0){
				g[j]=0;
			}
			if ((b[j] & 0x80)!=0){
				b[j]=0;
			}
			if (r[j]>7){
				r[j]=7;
			}
			if (g[j]>7){
				g[j]=7;
			}
			if (b[j]>3){
				b[j]=3;
			}
/*			if(x==256*127){
				printf("r=%3d g=%3d b=%3d bb=%3d\n",r[j],g[j],b[j],bb[j]);
			}
*/			sc8tmp=(g[j]*32+r[j]*4+b[j]) % 256;
			sc8data[i][j]=sc8tmp;
		}
		x+=4;
	}
	return(0);
}

/*********************************************************

			  			メイン

*********************************************************/


void main( int argc, char *argv[] ){
	fileno=0;
	mode=0x16;
	if(optionset( argc, argv )!=0){
		exit(-1);
	}
	for ( i = 0; i <251 ;i ++ ){
		if ( fname[i] != 0x2a ){
			flong += 1;
		}
		else {
			wildcard=1;
			break;
		}
	}
	if(wildcard==1){
		w_ret=_dos_findfirst((char*)fname,mode,&wildfbuf);
		if(w_ret){
			printf("指定のワイルドカ−ドが見つかりません\n");
			exit(-1);
		}
		else{
			strcpy(wildfname[fileno],wildfbuf.name);
			fileno++;
			for (;;){
				w_ret=_dos_findnext(&wildfbuf);
				if(w_ret){
					break;
				}
				strcpy(wildfname[fileno],wildfbuf.name);
				fileno++;
			}
		}
		for(wildct=0;wildct<fileno;wildct++){
			strcpy(fname,filepath);
			strcat(fname,wildfname[wildct]);
 			if(sccload()!=0){
				exit(-1);
			}
			if(convert()!=0){
				exit(-1);
			}
			strcpy(fname,wildfname[wildct]);
			if(sc8save()!=0){
				exit(-1);
			}
		}
	}
	else{
		if(sccload()!=0){
			exit(-1);
		}
		if(convert()!=0){
			exit(-1);
		}
		findflag=0;
		namelen=strlen(fname);
		flong=namelen;
		for ( i =namelen-1; (i+1)>0 ;i-- ){
			if ( fname[i] != 0x5c ){
				flong -= 1;
			}
			else {
				findflag=1;
				break;
			}
		}
		if(findflag==0){
			flong=1;
			for ( i = 0; i <255 ;i ++ ){
				if ( fname[i] != 0x3a ){
					flong += 1;
				}
				else {
					findflag=2;
					break;
				}
			}
		}
		if(findflag!=0){
			for(i=flong;i<namelen;i++){
				fname[i-flong]=fname[i];
			}
			fname[i-flong]=0;
		}
		if(sc8save()!=0){
			exit(-1);
		}
	}
	exit(0);
}
