/*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "defines.h"
#include "printer.h"
#include "abuff.h"

static int M;		/* 縦ドット数 */
static int BI;		/* 画面上の１ドットをプリンターで何倍するか(1/2/4/8) */
static int BY;		/* １バイトあたりのドット数 */
static int MM;		/* 縦１キャラクター印字に必要なバイト数 */
static int SZ;		/* １ラインデータバイト数 */
static unchar DOT;	/* その倍率における１ドットパターン */
static int PLANE;	/* コピープレーン番号 */
static unchar *TX;	/* そのプレーンのTEXT VRAM先頭アドレス */

/*****************************************************************************/

static int Hc4(int x,int gy,unchar *wrk)
{
unchar b,bb,c,tvram[8];
int i,j;
int f0=0; /* 0x00だけかどうか */
unchar *tx1;
	tx1=(unchar *)(TX+x+gy*128);
	for (i=0;i<BY;i++) {
		/* 画面を読む：機種依存はここだけ */
		tvram[i]=*tx1;
		if (PLANE>=4) { /* 2plane 重ね合わせ */
			tvram[i]|=*(tx1+TPSIZE);
		}
		tx1+=TLSIZE;
	}
	b=BIT7;
	for (j=0;j<8;j++) {
		bb=DOT; /* 縦拡大はDOTで行う */
		c=0;
		for (i=1;i<=BY;i++) {
			if (tvram[BY-i]&b) c|=bb;
			bb<<=BI;
		}
		for (i=0;i<BI;i++) { /* 横拡大 */
			*wrk=c;
			wrk+=(M/8);
		}
		b>>=1;
		if (c!=0) f0=1;
	}
	return(f0);
}

/*****************************************************************************/

static int Hc64(int x,int gy,unchar *wrk)
{
int i,f0=0;
	for (i=0;i<M/8;i++) {
		if (Hc4(x,gy+i*8/BI,wrk+i)) f0=1;
	}
	return(f0);
}

/*****************************************************************************/

int hcopy0(int sx,int sy,int ex,int ey,int bi,int plane)
/* プレーン別テキスト領域ハードコピー（４段階対応）*/
/* (sx,sy)-(ex,ey)=テキスト領域 , bi=倍率(1/2/4/8) plane=ﾃｷｽﾄﾌﾟﾚｰﾝ(0-3,4-5) */
{
int x,y,f0,i,stp;
unchar *pwrk;
#define BTSZ	6	/* ビットイメージコードのバイト数 */
#define CRSZ	6	/* n/360インチ改行コードのバイト数 */
static unchar cr[CRSZ]={0x0d,0x1b,'|','J',0,0}; /* n/360インチ改行 */

	BI=bi;		/* 画面上の１ドットをプリンターで何倍するか */
	stp=1+(bi==1);	/* １倍の時は２行単位のみ */
	M=16*bi*stp;	/* プリンター縦ドット数 */
	if (M>64) M=64;	/* 縦ドット数は最大６４（プリンターの都合による）*/
	BY=(8/bi);	/* １バイトあたりのドット数 */
	MM=(M/8*8*bi);	/* 縦１キャラクター印字に必要なバイト数 */
	SZ=(MM*(ex-sx+1));	 /* １ラインデータバイト数 */
	PLANE=plane;		 /* プレーン番号 */
	if (plane==4) plane=0;	/* plane0+1 */
	if (plane==5) plane=2;	/* plane2+3 */
	TX=(unchar *)(TPLANE0+plane*TPSIZE); /* そのプレーンの先頭アドレス */
	
	/* １行分データバッファー確保 */
	pwrk=newmalloc(BTSZ+SZ);
	if (pwrk==NULL) return(1);
	
	/* 先頭６バイトにビットイメージコードを入れておく */
	pwrk[0]=ESC;
	pwrk[1]='|';
	pwrk[2]='B';
	pwrk[3]=M;
	pwrk[4]=SZ%256;
	pwrk[5]=SZ/256;
	/* 改行幅設定 */
	cr[5]=M; /* n/360インチ改行 */
	
	/* その倍率における１ドットパターン */
	DOT=0;
	for (i=0;i<bi;i++) {
		DOT<<=1;
		DOT|=BIT0;
	}
	
	/* １行改行しておく */
	OUTLPT2(0x0d,0x0a);
	
	/* ハードコピーメイン */
	for (y=sy;y<=ey;y+=stp) {
		f0=0;
		for (i=0,x=sx;x<=ex;x++,i++) {
			f0+=Hc64(x,y*16,&pwrk[BTSZ+i*MM]);
		}
		if (f0) NLP(pwrk,BTSZ+SZ);
		/* 0x00のみの行は改行だけにする */
		NLP(cr,CRSZ);
		if (bi==8) {
			for (i=0,x=sx;x<=ex;x++,i++) {
				f0+=Hc64(x,y*16+8,&pwrk[BTSZ+i*MM]);
			}
			if (f0) NLP(pwrk,BTSZ+SZ);
			/* 0x00のみの行は改行だけにする */
			NLP(cr,CRSZ);
		}
	}
	
	free(pwrk);
	return(0);
}

/*****************************************************************************/
#if 0
main()
{
int ret;
	do {
		ret=hcopy0(0,0,79,24,1,1);
		if (ret) break;
		ret=hcopy0(0,0,79,24,2,1);
		if (ret) break;
		ret=hcopy0(0,0,79,24,4,1);
		if (ret) break;
		ret=hcopy0(0,0,39,12,8,1);
	} while (0);
	if (ret) printf("Error\n");
}
#endif
