/*
*	Yamana's Otomeza Plug-in Tool
*		Ｘwindow Ｂit Ｍap ローダ
*	
*	1993.11.17	DOS 用に作成
*	1995.08.07	乙女座プラグイン化
*	1995.08.08	あまりにも遅かったので一気に 320% ほど高速化(^^;)
*	1995.08.21	圧縮XBMが乱れるのを修正
*	
*/

#include	"otome_pi.h"

const char	longname[]	= "FILE  : XBM loader";
const char	extend[]	= "XBM";

#define		USE_FILE	PI_LOAD
#include	"otome_pi.c"


char	*readbuf,*buf;
char	*bufp;

/*************************************************************************/

#define	my_lower(c)		( ((c)>'Z') ? (c): ((c)+' ') )
#define	my_isdigit(c)	( ((c) >='0' && (c)<= '9') ? 1:0 )

/* 英字のときチェックしない */
#define	my_ishex(c)		( ((c)>='0' && (c)<='9') ? \
								((c)-'0') : (my_lower(c)-'a'+10) )

int my_ishex2(int c)
{	
		 if (c >='a' && c <='f')	return(1);
	else if (c >='0' && c <='9')	return(1);
	else if (c >='A' && c <='F')	return(1);
	else							return(0);
}

/***********************/

#define		TMPMAX	80

int XBM_get_size( num,str,fp )
int 	*num;
char	*str;
FILE	*fp;
{
	char	tmp[ TMPMAX+1 ];
	char	*p;
	
	while( !feof(fp) )
	{	if(     fgets( tmp, TMPMAX ,fp	) ==NULL )	return ERROR;
		if( (p=strstr( tmp, "#define"	))==NULL )	continue;
		if( (p=strstr( p  , str 		))==NULL )	continue;
		break;
	}
	/* 数字を探す */
	while( *p !='\0' && strchr( "0123456789", *p )==NULL )	p++;
	
	*num = atoi( p );
	return NOERR;
}


int XBM_getSize( size,fp )
POINT	*size;
FILE	*fp;
{
	int 	i;
	
	if( XBM_get_size( &i,"width",fp )==ERROR || i<=0 )	return ERROR;
	size->x = (short)i ;
	
	if( XBM_get_size( &i,"height",fp)==ERROR || i<=0 )	return ERROR;
	size->y = (short)i ;
	
	return NOERR;
}

/***********************/

char	xchg_bit( c )
char	c;
{
	int 	i;
	char	tmp;
	
	for( i=0,tmp=0 ; i<8 ; i++, c>>=1 )
		tmp |= ( (c&1) << (7-i) );
	
	return tmp;
}

#define		LIMIT_COMM	" ,\r\n\t{};"

int XBM_load( image, size )
char	*image;
POINT	*size;
{	
	int 	i,xs,bxs,val,pat;
	int 	off,all;
	
	/* 32ビット単位で扱われる	*/
	xs  = (size->x+ 7)>>3 ;				/*  8 */
	bxs =((size->x+31)& 0xffe0)>>3 ;	/* 32 */
	all = bxs * size->y ;
	
	pat = (bxs-xs) ;
	
	bufp = readbuf;
	if( (bufp = strstr( bufp, "char"   ))==NULL )	return ERROR;
	if( (bufp = strstr( bufp, "_bits[]"))==NULL )	return ERROR;
	if( (bufp = strstr( bufp, "{"      ))==NULL )	return ERROR;
	
	while( *bufp !='\0' && strchr( LIMIT_COMM, *bufp ) )	bufp++;
	off= 0;
	while( off<all && bufp!=NULL )
	{	
		if( bufp[1] == 'x' || bufp[1] == 'X' )
		{	val = (my_ishex( bufp[2] )<<4) | my_ishex( bufp[3] ) ;
			bufp+=4;
		}
		else
		{	/* 圧縮 XBM */
			if( (bufp[1]>='0' && bufp[1]<='9') || 
				(bufp[1]>='a' && bufp[1]<='f') || 
				(bufp[1]>='A' && bufp[1]<='F')		)
			{	val = (my_ishex( bufp[0] )<<4) | my_ishex( bufp[1] );
				bufp+=2;
			}
			else
			{	val = my_ishex( bufp[0] );
				bufp+=1;
			}
		}
		
		image[ off++ ] = xchg_bit(val);
		
		if( pat && (off % bxs)>=xs )
			for( i=0; i<pat; i++ )
				image[ off++ ] = 0;
		
		
		while( *bufp!='\0' && strchr( LIMIT_COMM, *bufp ) )	bufp++;
		
	}
	
	return NOERR;
}

long	getFileSize( fp )
FILE	*fp;
{
	unsigned long	from,to;
	
	from = ftell(fp);
	fseek( fp, 0, SEEK_END );
	to = ftell(fp);
	fseek( fp, from, SEEK_SET );
	
	return (to-from);
}

/********************/

int APL_exec()
{
	FILE	*fp;
	char	*image;
	int 	fsize;
	POINT	size;
	
	if( (fp = fopen( PI_FNAME , "rb" )) == NULL )
		return PI_ERROR_FILE_OPEN;
	
	if( XBM_getSize( &size, fp ) )
	{	fclose(fp);
		return ERROR;
	}
	
	if( (readbuf=PI_MALLOC( (fsize=getFileSize(fp))+1 ))==NULL )
	{	fclose(fp);
		return PI_ERROR_NO_MEMORY;
	}
	
	if( (image=PI_MALLOC( ((size.x+31)& 0xffe0)*size.y ))==NULL )
	{	fclose(fp);
		PI_FREE( readbuf );
		return PI_ERROR_NO_MEMORY;
	}
	
	fread( readbuf, 1,fsize, fp ), readbuf[fsize]='\0';
	fclose(fp);
	
	if( XBM_load( image, &size ) )
	{	PI_FREE( image );
		PI_FREE( readbuf );
		return ERROR;
	}
	PI_FREE( readbuf );
	
	pi_imge->image	= image;
	pi_imge->pix	= 1;
	pi_imge->size.x = size.x;
	pi_imge->size.y = size.y;
	
	return NOERR;
}

