
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <egb.h>
#include <spr.h>
#include <snd.h>
#include <fif.h>
#include <fmc.h>

#define VERSION "1.02"
#define	SPRNUM	1024-160
#define ESC		0x1b
#define RIGHT	0x1c
#define LEFT	0x1d
#define UP		0x1e
#define DOWN	0x1f

char path[]="q:\\data\\";
char buffer[0x20000];
char col[8192];
char idx[500][250];
char dat[50][20482];
char egb_work[1536], msg[256];
char same[256];
int number=0, number_max, param=0, param_max, pal=0, pal_max, direction=1;
int key, shift, ctrl, color=0, sx, sy, rx=0, ry=0, mul=2;
FILE *fp;

extern void crtcout(int crtcreg, int data);
extern void save_r(char *buffer);
extern void load_r(char *buffer);
extern void print_3(int x, int y, int col, char *str, int len);

char joy_stick()
{
	char s, mem=0xff;
	int cnt, status;
	do {
		SND_joy_in_2(0, &status);
		s = ~status;
		SND_joy_in_2(1, &status);
		s |= ~status;
		if (s!=mem) {
			cnt=0;
			mem=s;
		}
	} while (++cnt<16);
	return s;
}

char joy_repeat()
{
	static char cnt, mem=0xff;
	int s;
	if ((s=joy_stick())!=mem) {
		cnt=0;
		return mem=s;
	}
	if (++cnt<32) return 0;
	cnt--;
	return s;
} 

void scroll()
{
	int i;
	i=joy_repeat();
	if (i & 1) ry--;
	if (i & 2) ry++;
	if (i & 4) rx--;
	if (i & 8) rx++;
	if (i==0x10 && mul<16) mul++;
	if (i==0x20 && mul>2) mul--;
	if (i & 0xc0) {
			mul=2;
			rx=ry=0;
	}
	if (_abs(rx)>(i=sx*8)) rx=(rx>=0 ? i: -i);
	if (_abs(ry)>(i=sy*8)) ry=(ry>=0 ? i: -i);
	SPR_setPosition(0, SPRNUM, sx, sy, 256/mul-sx*8-rx, 336/mul-sy*8-ry);
	crtcout(27, (mul-1)*0x1100+0x11);
	SPR_display(2, 160);
}

void print_msg(x, y, col)
int x, y, col;
{
	print_3(x, y, col, msg, strlen(msg));
}

void input(sw)
int sw;
{
	unsigned i;
	key=KYB_read(sw, &i);
	shift=i & 4;
	ctrl=i & 0x10;
}

void sprite_erase()
{
/*	SPR_setPosition(0, SPRNUM, 16, 10, 256, 0);*/
	SPR_setAttribute(SPRNUM, 16, 10, 0, 0xa100);
}

void print_block()
{
	int i=same[pal];
	sprintf(msg, "PALETTE BLOCK %3d (%02X)", i, i);
	print_msg(5, 3, 7);
	sprintf(msg, "PALETTE SORT %3d (Max %3d)", pal, pal_max-1);
	print_msg(5, 4, 7);
	SPR_setAttribute(SPRNUM, sx, sy, 128, same[pal]+0x8100);
}

void display_object()
{
	char *ptr;
	int i=-1;
	param=(direction>=0 ? 0 : param_max-1);
	for (;;) {
		if (param!=i) {
			ptr=&idx[number][(i=param)*5];
			sprite_erase();
			SPR_define(0, 128, sx=ptr[0], sy=ptr[1], &dat[i][0]);
			sprintf(msg, "OBJECT NUMBER %2d - %2d (Max %2d)", number+1, i+1, param_max);
			print_msg(5, 1, 7);
			sprintf(msg, "INDEX DATA %02X %02X %02X %02X %02X", sx, sy, ptr[2], ptr[3], ptr[4]);
			print_msg(5, 2, 7);
			print_block();
		}
		scroll();
		input(1);
		switch (key) {
			case ESC:
				return;
			case UP:
				pal -= (ctrl ? (shift ? 0x40 : 0x20) : (shift ? 0x10 : 1));
				break;
			case DOWN:
				pal += (ctrl ? (shift ? 0x40 : 0x20) : (shift ? 0x10 : 1));
				break;
			case RIGHT:
				if (shift==0 && ctrl==0 && ++param<param_max) continue;
				direction=+(ctrl ? (shift ? 20 : 5) : 1);
				return;
			case LEFT:
				if (shift==0 && ctrl==0 && --param>=0) continue;
				direction=-(ctrl ? (shift ? 20 : 5) : 1);
				return;
			default:
				continue;
		}
		while (pal<0) pal+=pal_max;
		while (pal>=pal_max) pal-=pal_max;
		print_block();
	}
}

void clear_msg()
{
	strcpy(msg, "                                          ");
	print_msg(0, 7, 7);
	print_msg(0, 8, 7);
	if (++color==7) color++;
	if (color>=15) color=0;
}

void display_main()
{
	char *ptr;
	int i;
	strcpy(msg, "オブジェクト表示  Ver" VERSION "  by Yasu.Hara.");
	print_msg(0, 0, 15);
	do {
		strcpy(msg, "データを読み込んでいま〜すっ ☆彡");
		print_msg(4, 7, color);
		strcpy(msg, "ちょっと待ってくださいね〜♪(^_^)");
		print_msg(4, 8, color);
		ptr=&idx[number][0];
		for (i=0; i<50; i++)
			if (ptr[i*5]==0 || ptr[i*5+1]==0) break;
		if ((param_max=i)!=0) {
			fseek(fp, number*sizeof(dat), SEEK_SET);
			i--;
			fread(dat, 1, i=i*20482+ptr[i*5]*ptr[i*5+1]*128, fp);
			if (_skip_char(dat, i, 0)<i) {
				clear_msg();
				display_object();
				sprite_erase();
			}
		}
		number+=direction;
		if (number<0) number=number_max-1;
		if (number>=number_max) number=0;
		direction=(direction>=0 ? 1 : -1);
	} while (key!=ESC);
}

void file_open(ptr)
char *ptr;
{
	char filename[256];
	sprintf(filename, "%s%s", path, ptr);
	while ((fp=fopen(filename, "rb"))==NULL) {
		if (filename[0]<'q') {
			filename[0]='q';
			continue;
		}
		strcpy(msg, "富士通ＨａｂｉｔａｔのＣＤ−ＲＯＭを入れ");
		print_msg(0, 7, color);
		strcpy(msg, "何かキーを押してくださいませぇ〜♪(^_^;)");
		print_msg(0, 8, color);
		input(0);
		clear_msg();
		if (key==ESC) exit(1);
	}
}

void same_check()
{
	char *ptr;
	int i, j;
	pal_max=0;
	for (i=0; i<256; i++) {
		ptr=&col[i*32];
		for (j=0; j<pal_max; j++) {
			if (memcmp(&col[same[j]*32], ptr, 32)==0) goto SAME_EXIST;
		}
		same[pal_max++]=i;
		SAME_EXIST: ;
	}
}

void main(argc, argv)
int argc;
char *argv[];
{
	int i;
	if (argc==2 && (i=(*argv[1]|0x20))>='a' && i<='q') path[0]=i;
	EGB_init(egb_work, sizeof(egb_work));
	EGB_resolution(egb_work, 0, 3);
	EGB_resolution(egb_work, 1, 5);
	EGB_displayPage(egb_work, 0, 3);
	EGB_writePage(egb_work, 1);
	EGB_displayStart(egb_work, 2, 2, 2);
	EGB_displayStart(egb_work, 0, 32, 0);
	EGB_displayStart(egb_work, 3, 256, 256);
	EGB_writePage(egb_work, 0);
	EGB_displayStart(egb_work, 2, 2, 2);
	EGB_displayStart(egb_work, 3, 256, 256);
	SND_elevol_init();
	file_open("palette.32k");
	fread(col, 1, sizeof(col), fp);
	fclose(fp);
	file_open("object.idx");
	number_max=fread(idx, 1, sizeof(idx), fp)/250;
	fclose(fp);
	file_open("object.dat");
	same_check();
	save_r(buffer);
	SPR_init();
	SPR_display(1, 160);
	sprite_erase();
	SPR_setPaletteBlock(256, 256, col);
	display_main();
	SPR_display(2, 160);
	SPR_display(0, 1024);
	load_r(buffer);
	fclose(fp);
}
