
#include	<stdio.h>
#include	<string.h>
#include	<dos.h>

#define 	put_spr		PUT_SPR
#define 	clr_spr		CLR_SPR

extern	void	put_spr(int vram,char *ptr);
extern	void	clr_spr(int vram);

char	path[256],filename[256];
char	pattern[30][512];
int 	palette[3][16];
int 	max,pb=1;
FILE	*fp;

/* テキスト画面に１文字表示する */
void	putchr(chr)
int		chr;
{
	union	REGS	regs;

	if (chr=='\n') {
		regs.h.al=0xd;
		regs.h.ah=0x1d;
		int86(0x91, &regs, &regs);
	}
	regs.h.al=chr;
	regs.h.ah=0x1d;
	int86(0x91, &regs, &regs);
}

/* テキスト画面に文字列を表示する */
void	print(msg)
char	*msg;
{
	int		i;

	while  (i=*msg++) 
		putchr(i);
}

void	print_dec(no,keta)
int 	no,keta;
{
	char	ptr[16];
	ptr[keta]='\0';
	do {
		ptr[--keta]=no % 10 | '0';
		no/=10;
	} while (keta>0);
	print(ptr);	
}

/* テキスト文字の色・属性を設定する */
void	color(col, attr)
int		col, attr;
{
	static	char	buffer[4]={0, 0, 0, 0};
	union	REGS	regs;

	buffer[1]=attr;
	buffer[2]=col;
	regs.h.ah=0x11;
	regs.x.di=(int)buffer;
	int86(0x91, &regs, &regs);
}

/* リアルタイム文字入力 */
int		inkey()
{
	union	REGS	regs;

	regs.x.ax=0x901;
	int86(0x90, &regs, &regs);
	return regs.h.dh!=0xff ? regs.h.dl : 0;
}

/* テキスト画面を消去する */
void	cls()
{
	union	REGS	regs;

	color(7, 0);
	regs.h.ah=2;
	int86(0x91, &regs, &regs);
}

/* 指定した位置座標にカーソルを移動する */
void	locate(x, y)
int		x, y;
{
	union	REGS	regs;

	regs.h.ah=0xd;
	regs.h.dh=y+1;
	regs.h.dl=x+1;
	int86(0x91, &regs, &regs);
}

/* システム行の表示・非表示を設定する */
void	system_line(sw)
int		sw;
{
	union	REGS	regs;

	regs.h.ah=0x1b;
	regs.h.al=sw ? 0xc2 : 0x82;
	int86(0x91, &regs, &regs);
}

/* カーソルの表示・非表示を設定する */
void	cursor(sw)
int		sw;
{
	union	REGS	regs;

	regs.h.ah=0xb;
	regs.h.al=sw ? 0 : 1;
	int86(0x91, &regs, &regs);
}

void	title()
{
	print("アバタヘッド表示 for FMＲ-５０ Ver1.00\n");
	print("  Programmed by Ｙａｓｕ．Ｈａｒａ．\n");
}

void	usage()
{
	title();
	print("    使用法 : head <ヘッドデータの入っているパス>\n");
	print("        例 : head d:\\habitat\\data\n");
	exit(1);
}

void	put_sprite(x,y,no)
int 	x,y,no;
{
	char	*ptr;
	int 	i;
	put_spr(i=y*80+x,ptr=&pattern[no][0]);
	put_spr(i+4,ptr+=128);
	put_spr(i+=2560,ptr+=128);
	put_spr(i+4,ptr+=128);
}

void	clr_sprite(x,y)
int 	x,y;
{
	int 	i;
	clr_spr(i=y*80+x);
	clr_spr(i+4);
	clr_spr(i+=2560);
	clr_spr(i+4);
}

void	ginit()
{
	union	REGS	regs;
	regs.x.ax=0xf901;
	int86(0x92,&regs,&regs);
	regs.x.ax=0xfa04;
	int86(0x92,&regs,&regs);
	regs.h.ah=0x80;
	int86(0x92,&regs,&regs);
}

void	pal_block(no)
int 	no;
{
	static	int 	buffer[49]={96, 0,0xf000,0xf0f0,
		1,0,0,  2,0,0,  3,0,0,  4,0,0,  5,0,0,  6,0,0,  7,0,0,
		8,0,0,  9,0,0, 10,0,0, 11,0,0, 12,0,0, 13,0,0, 14,0,0, 15,0,0
	};
	char	*ptr;
	int 	i,j;
	union	REGS	regs;
	struct	SREGS	sregs;
	locate(34,0);
	print("パレットブロック : ");
	putchr(no+'0');
	for (i=1;i<16;i++) {
		ptr=(char *)buffer+i*6;
		j=palette[no][i];
		ptr[5]=j>>2 & 0xf8;
		ptr[6]=j>>7 & 0xf8;
		ptr[7]=j<<3;
	}
	segread(&sregs);
	sregs.ds=(long)buffer>>16;
	regs.x.di=(int)buffer;
	regs.h.ah=0x83;
	int86x(0x92,&regs,&regs,&sregs);
}

void	file_open(data)
char	*data;
{
	strcpy(filename,path);
	strcat(filename,data);
	if ((fp=fopen(filename,"rb"))!=NULL) return;
	print("ファイル ");
	print(filename);
	print(" が見つかりません\n");
	exit(1);
}

void	disp(start)
int 	start;
{
	int 	i=0,x,y,d;
	fseek(fp,(long)start*(long)1536,SEEK_SET);
	fread(pattern,1,sizeof(pattern),fp);
	for (x=0;x<2;x++) {
		for (y=0;y<5;y++) {
			locate(x*40+3,y*5+3);
			if (start++<max) {
				print_dec(start,4);
				for (d=0;d<3;d++)
					put_sprite(x*40+d*10+10,y*79+18,i++);
			} else {
				print("    ");
				for (d=0;d<3;d++)
					clr_sprite(x*40+d*10+10,y*79+18);
			}
		}
	}
}

void	head_main()
{
	int 	i,pb,pat,jump;
	ginit();
	cls();
	color(0,0);
	fseek(fp,(long)0,SEEK_END);
	locate(10,0);
	print("ヘッドの種類 : ");
	print_dec(max=ftell(fp)/1536,4);
	pal_block(pb=1);
	disp(pat=jump=0);
	i='0';
	do {
		switch (i) {
			case 0x1c:
				if ((pat+=10)>=max) pat-=max;
				disp(pat);
				break;
			case 0x1d:
				if ((pat-=10)<0) pat+=max;
				disp(pat);
				break;
			case 0x1e:
				if (--pb<0) pb=0;
				pal_block(pb);
				break;
			case 0x1f:
				if (++pb>2) pb=2;
				pal_block(pb);
				break;
			default:
				if (i!=0xd) {
					if ((unsigned)(i-='0')>9) break;
					locate(60,0);
					print("JUMP : ");
					print_dec(jump=jump%1000*10+i,4);
				}
				if (jump>0 && jump<=max && (i=(jump-1)/10*10)!=pat)
					disp(pat=i);
		}
	} while ((i=inkey())!=0x1b);
	ginit();
	cls();
}

int 	main(argc,argv)
int 	argc;
char	*argv[];
{
	int 	i;
	if (argc<2) usage();
	strcpy(path,argv[1]);
	strupr(path);
	if ((i=path[strlen(path)-1])!='\\' && i!=':') strcat(path,"\\");
	file_open("PALETTE.32K");
	fread(palette,1,sizeof(palette),fp);
	fclose(fp);
	file_open("HEAD.DAT");
	system_line(0);
	cursor(0);
	head_main();
	fclose(fp);
	system_line(1);
	cursor(1);
	title();
	print("    ばいば〜い、また見てね〜(^_^;)\n");
	return 0;
}
