/*
**  ESCP.C    1995.5  by JOUJI
**
**  使い方：escp { file_name | /parameter } ...
**
**  '/'で始まる文字列はパラメーターとして扱われる。"$xx"は１６進データ。
*/

#include <stdio.h>
#include <stdlib.h>
#include <jctype.h>

void print_file(char *fname);
void print_cc(char *cc);
char _asm_p();

/*
static char kata[] = "｡｢｣､･ｦｧｨｩｪｫｬｭｮｯｰｱｲｳｴｵｶｷｸｹｺｻｼｽｾｿﾀﾁﾂﾃﾄﾅﾆﾇﾈﾉﾊﾋﾌﾍﾎﾏﾐﾑﾒﾓﾔﾕﾖﾗﾘﾙﾚﾛﾜﾝﾞﾟ";
*/
static char zenkata[] = "　。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゛゜";
static char line[256];
static int fh = 0;

#ifdef TOWNS
/* ＦＭＲ＆ＴＯＷＮＳ ＢＩＯＳ */
#define bios_asm(x) \
	_asm_p("\n\tINT\t94H\n", 0x100, _asm_p, _asm_p, (char)(x))
#else
/* ＦＭＶ用 ＩＢＭ／ＰＣ ＢＩＯＳ */
#define bios_asm(x) \
	_asm_p("\n\tMOV\tAH,0\n\tINT\t17H\n", (char)(x), _asm_p, _asm_p, 0)
#endif

void bios_print(char c)
{
	char d;
	union {
		unsigned short w;
		struct {
			char l;
			char h;
		} b;
	} ax;

	for(;;) {
		ax.w = bios_asm(c);
#ifdef TOWNS
		if(!ax.b.h) return;
#else
		if(!(ax.b.h & '\x01')) return;
#endif
		if(kbhit()) {
			d = getch();
			if(d == '\x1b' || d == '\x03') exit(2);
		}
	}
}

main(int argc,char *argv[])
{
	int i;

	if (argc<2) {
		puts("Parameter error !\n");
		exit(1);
	}
	for(i=1; i<argc; i++) {
		if(argv[i][0] == '/') {
			print_cc(argv[i]);
		} else {
			print_file(argv[i]);
		}
	}
	if( fh ) {
		bios_print(0x1c);			/* 半角モード解除 */
		bios_print(0x12);
	}
}

char hex2char(char *p)
{
	char x, y, c;

	x=0;
	c=toupper(*(p++));
	x = (c>='0' && c<='9') ? c - '0' : c - '7';
	c=toupper(*p);
	y = (c>='0' && c<='9') ? c - '0' : c - '7';
	x=(x << 4) + y;
	return x;
}

void PrintControl(void)
{
	char c, *p;
	int  i;
	FILE  *fq;

	if(line[0] == 0x03) {			/* ^C:コメント */
		return;
	} else if(line[0] == 0x05) {	/* ^E:16進データ */
		for(p = line + 1; *p != '\n'; p += 2) {
			c = hex2char(p);
			bios_print(c);
		}
	} else if(line[0] == 0x06) {	/* ^F:ビット・イメージ・データ・ファイル */
		for(i=1; i<255; i++) {
			if(line[i] == '\n') {
				line[i] = '\0';
				break;
			}
		}
		if( (fq=fopen(&line[1], "rb")) == NULL) {
			puts("File not exist !\n");
			return;
		}
		while((i=fgetc(fq)) != EOF)
			bios_print(i);
		fclose(fq);
	} else if(line[0] == 0x0a) {	/* ^J:空行 */
		bios_print(0x0d);
		bios_print(0x0a);
	} else {
		for(i=0; i<255; i++) {
			c = line[i];
			if(c == '\n' || c == '\0')
				break;
			bios_print(c);
		}
	}
}

void PrintLine(void)
{
	unsigned char c, d;
	int  i, x;
	union {
		unsigned short w;
		struct {
			char l;
			char h;
		} b;
	} sjis, jis;

	for(i=0; i<255; i++) {
		c = line[i];
		if(c == '\n' || c == '\0')
			break;
		if( iskanji(c) ) {
			d = line[++i];
			if(d == '\n' || d == '\0') break;
			sjis.b.h = c;
			sjis.b.l = d;
			jis.w = mstojis(sjis.w);
			if( fh ) {
				bios_print(0x1c);	/* 半角モード解除 */
				bios_print(0x12);
				fh = 0;
			}
			bios_print(jis.b.h);
			bios_print(jis.b.l);
		} else if(c >= 0xa0) {
			x = c - 0xa0;
			x += x;
			sjis.b.h = zenkata[x++];
			sjis.b.l = zenkata[x];
			jis.w = mstojis(sjis.w);
			if( !fh ) {
				bios_print(0x1c);	/* 半角モード指定 */
				bios_print(0x0f);
				fh = 1;
			}
			bios_print(jis.b.h);
			bios_print(jis.b.l);
		} else if(c >= 0x20) {
			sjis.w = hantozen(c);
			jis.w = mstojis(sjis.w);
			if( !fh ) {
				bios_print(0x1c);	/* 半角モード指定 */
				bios_print(0x0f);
				fh = 1;
			}
			bios_print(jis.b.h);
			bios_print(jis.b.l);
		} else {
			bios_print(c);
		}
	}
}

void print_file(char *fname)
{
	FILE *fp;

	if( (fp=fopen(fname,"r")) == NULL) {
		puts("File not exist !\n");
		return;
	}
/*	fgets(line, 256, fp); */ /* ファイルの最初の一行無視 */
	while( fgets(line, 256, fp) != NULL) {
		if(line[0] <= 0x1f) {
			PrintControl();
		}
		else {
			PrintLine();
		}
	}
	fclose(fp);
}

void print_cc(char *p)
{
	char c;

	for( p++; *p != '\0'; p++ ) {
		c = *p;
		if( c == '$' ) {
			c = hex2char(++p);
			p++;
		}
		bios_print(c);
	}
}
