#include<stdio.h>
#include <string.h>
#include <mem.h>
#include<stdlib.h>
#include<dos.h>
#include<conio.h>
#include<alloc.h>


char *screen1=(char *)MK_FP(0xa000,0x0000);
char *screen;

char Level;

#define Size 6400

int Num;

int *Data;



int Reset()
{
struct REGPACK reg;
reg.r_ax = 0x0000;
intr(0x33,&reg);
return reg.r_ax;
}

int Retstat(int *x,int *y){
struct REGPACK reg;
reg.r_ax = 0x0003;
intr(0x33,&reg);
*x=reg.r_cx;
*y=reg.r_dx;
return reg.r_bx;
}

void SetOptimPal()
{
struct REGPACK reg;
reg.r_ax = 0x1010;
reg.r_bx = 255;
reg.r_cx = 0;
reg.r_dx = 0;
intr(0x10,&reg);
reg.r_ax = 0x1010;
reg.r_bx = 254;
reg.r_cx = 32;
reg.r_dx = 0;
intr(0x10,&reg);
for(int i=0;i<240;i++)
{
reg.r_ax = 0x1010;
reg.r_bx = i;
reg.r_cx = (random(32)+32)+256*(random(32)+32);
reg.r_dx = (random(32)+32)*256;
intr(0x10,&reg);
}
}

void Show()
{
struct REGPACK reg;
reg.r_ax = 0x0001;
intr(0x33,&reg);
}

void Hide(){
struct REGPACK reg;
reg.r_ax = 0x0002;
intr(0x33,&reg);
}


void Rect(int x1,int y1,int x2,int y2,int c)
{
for(int y=y1;y<=y2;y++)
	{
	setmem(screen+y*320+x1,x2-x1+1,c);
	}
}

void Drawarea(int n,int c)
{
for(int l=0;l<Num;l++)
if(*(Data+l*10)==n)
	{
	Rect(*(Data+l*10+2),*(Data+l*10+4),*(Data+l*10+6),*(Data+l*10+8),c);
	}
}

void Redraw()
{
for(int l=0;l<Num;l++)
{
Rect(*(Data+l*10+2),*(Data+l*10+4),*(Data+l*10+6),*(Data+l*10+8),*(Data+l*10));
}
Hide();
memcpy(screen1,screen,64000);
Show();
}


void Dealloc()
{
free(Data);
free(screen);
}




int ReadData(FILE *f)
{
char str[16];
long length;
fseek(f, 0L, SEEK_END);
length = ftell(f);
fseek(f,0L, SEEK_SET);


fscanf(f,"%s\n",str);
Level=str[strlen(str)-1]-'0';
if((Data=(int *)malloc(Size*5*sizeof(int))) == NULL)
	{
	printf("Not enough memory to allocate map buffer\n");
	exit(1);
	}
for(Num=0;;Num++)
	{
	if(Num>=Size)
		{
		printf("Too big file\n");
		exit(1);
		}
//	fscanf(f,"%d %d %d %d\n",Data+Num*10,Data+Num*10+2,Data+Num*10+4,Data+Num*10+6,Data+Num*10+8);
	for(int u=0;u<10;u+=2)fscanf(f,"%ld",Data+Num*10+u);
	if(ftell(f)>=length)
		{
		break;
		}
	}
//Num++;
}

void VGA()
{
struct REGPACK reg;
reg.r_ax = 0x0013;
intr(0x10,&reg);
}

void TEXT()
{
struct REGPACK reg;
reg.r_ax = 0x0003;
intr(0x10,&reg);
}

void Decode(int x,int y){
static int fl=-1;
if(fl>=0)
Drawarea(fl,fl);
for(int l=0;l<Num;l++)
{
if(x>=*(Data+l*10+2)&&x<=*(Data+l*10+6)&&y>=*(Data+l*10+4)&&y<=*(Data+l*10+8))
	{
	fl=*(Data+l*10);
	Drawarea(fl,255);
	}
}
}

void Test(){
int x,y;
int s;
for(;;)
	{
	s=Retstat(&x,&y);
	if(s!=0){

		Decode(x/2,y);
		Hide();
		memcpy(screen1,screen,64000);
		Show();
		}
	if(kbhit())
		{
		if(getch()==27)
			{
			break;
			}
		}
	}
}


int main(int _argc,char *_argv[]){
FILE *in;
if((screen=(char *)malloc(64000)) == NULL)
	{
	printf("Not enough memory to allocate graphics buffer\n");
	exit(1);
	}
setmem(screen,64000,254);
if(_argc<2){
	printf("You must write '20mview xxxxxxxx.mdf'");
	exit(2);}
if((in=fopen(_argv[1],"rb"))==NULL)
	{
	printf("Cannot open input file.\n");
	exit(3);
	}
ReadData(in);
VGA();
printf("Initializing...");
SetOptimPal();
Redraw();
Reset();
Show();
Test();
Hide();
TEXT();
Dealloc();
}
