#include <stdio.h>
#include <dos.h>

/*#define MD_DEBUG*/
#define MD_PAL

#define CALL_MASK 2
#define COL1 240
#define COL2 241
#define DE   200
#define DEEE 800

typedef struct rect_s { int x1, y1, x2, y2;
			void *next;
			} rect_t;


unsigned char Level;
rect_t **Region;
int index, x1, y1, x2, y2;
unsigned int _addr_;
unsigned char _pxl_;
unsigned char _pal_[768];

void Plot (int x, int y, unsigned char color)
{
  pokeb(0xA000, (320*y)+x, color);
  }
unsigned char GetPix (int x, int y)
{
  return (peekb(0xA000, (320*y)+x));
  }

void SWGC_on(void) { asm { mov ax,1; int 0x33 } }
void SWGC_off(void) { asm { mov ax,2; int 0x33 } }

void SetPalMode (void)
{
  struct REGPACK r;
  struct SREGS s;
  segread(&s);
  r.r_ax = 0x0013;
  intr(0x10,&r);
#ifdef MD_PAL
  r.r_ax = 0x1012;
  r.r_bx = 0;
  r.r_cx = 256;
  r.r_dx = (unsigned short)(&_pal_[0]);
  r.r_es = s.ds;
  intr(0x10,&r);
#endif
  }

void DrawSquare (int x1, int y1, int x2, int y2, unsigned char col)
{
  int i, j;
  if (x1>x2) { x1^=x2; x2^=x1; x1^=x2; }
  if (y1>y2) { y1^=y2; y2^=y1; y1^=y2; }
  if (y1<0) y1=0;
  if (y2>199) y2=199;
  if (x1<0) x1=0;
  if (x2>319) x2=319;

  for (i=y1; i<=y2; i++)
      for (j=x1; j<=x2; j++)
	  Plot(j,i,col);
  }

void DrawRegions(void)
{
  int i;
  rect_t *p;

  SWGC_off();
  for (i=0; i<239; i++) {
      p = Region[i];
      while (p) {
	DrawSquare(p->x1, p->y1, p->x2, p->y2, i+1);
	p=(rect_t *)(p->next);
	}
      }
  }

void SelectRegion (unsigned char col)
{
  int sw, i, j;
  unsigned char c;

  for (i=0; i<320; i++) {
      sw = 0;
      c = (i&1)?COL1:COL2;
      for (j=0; j<200; j++) {
	  if (!sw && GetPix(i,j) == col) { /* border */
	     Plot(i,j,c);
	     sw = 1;
	     }
	  else if (sw && GetPix(i,j) != col) { /* border */
		  Plot(i,j-1,c);
		  sw = 0;
		  }
	  }
      if (sw) Plot(i,j-1,c);
      }
  for (i=0; i<200; i++) {
      sw = 0;
      c = (i&1)?COL1:COL2;
      for (j=0; j<320; j++) {
	  if (!sw && GetPix(j,i) == col) { /* border */
	     Plot(j,i,c);
	     sw = 1;
	     }
	  else if (sw && GetPix(j,i) != col) { /* border */
		  Plot(j-1,i,c);
		  sw = 0;
		  }
	  }
      if (sw) Plot(j-1,i,c);
      }
  }

int main (int argc, char **argv)
{
  FILE *f;
  rect_t **p;
  long i;
  int r, k;
  char pass;
  unsigned char c;
  struct REGPACK R;

  if (argc < 2) { puts ("No input file."); return (-1); }
  R.r_ax = 0;
  intr(0x33,&R);
  printf("Mouse check ... ");
  delay(DE);
  if (R.r_ax != 0xFFFF) { puts("failed"); return (-1); }
  printf("OK\n  Buttons ... %d\n",R.r_bx);
  delay(DE);
  printf("Opening input file '%s' ... ", argv[1]);
  if (!(f=fopen(argv[1],"rt"))) { puts("failed"); return (-1); }
  delay(DE);
  fscanf(f,"MDF/%d",&Level);
  printf("OK\nFile is level %d ... ",Level);
  delay(DE);
  if (Level > 4 || Level < 1) { puts ("unsupported"); return (-1); }
  fputs("OK\nReading file ... ",stdout);
  if (!(Region=(rect_t **)malloc(sizeof(int *)*239))) { puts("Out of memory."); return (-1); }
  for (i=0; i<239; Region[i++]=NULL);
  for (pass=1;!feof(f)&&pass;) {
      c=fscanf(f,"%i %i %i %i %i",&index, &x1, &y1, &x2, &y2);
      if (c==5) {
#ifdef MD_DEBUG
	 printf("{(%d)[%i,%i][%i,%i]}",index, x1, y1, x2, y2);
#endif
	 if (index > 239) { puts("Wrong index."); return (-1); }
	 for (p = &(Region[index-1]); *p; p=(rect_t **)(&((*p)->next)));
	 if (!((*p)=(rect_t *)malloc(sizeof(rect_t)))) { puts("Out of memory."); return (-1); }
	 (*p)->x1 = x1;
	 (*p)->y1 = y1;
	 (*p)->x2 = x2;
	 (*p)->y2 = y2;
	 (*p)->next = NULL;
	 }
      else pass = 0;
      }
  puts("OK\nEnabling graphics.");
  delay(DEEE);
  fclose(f);

  _pal_[0] = _pal_[1] = _pal_[2] = 0;
  for (i=1; i<240; i++) {
      _pal_[3*i  ] = ((i>>5)*255)/7;
      _pal_[3*i+1] = (((i>>2) & 7) * 255) / 7;
      _pal_[3*i+2] = ((i&3)*255)/3;
      }
  _pal_[3*240] = 30;
  _pal_[3*240+1] = 0;
  _pal_[3*240+1] = 0;
  _pal_[3*241] = 63;
  _pal_[3*241+1] = 63;
  _pal_[3*241+1] = 63;
  SetPalMode();

  asm { mov ax,1; int 0x33 }
  DrawRegions();
  SWGC_on();

  for (pass = 1, k=0; pass;) {
    if (kbhit()) {
       k=getch();
       if (k == 27) pass = 0;
       }
    R.r_ax = 3;
    intr(0x33,&R);
    if (R.r_bx&1) {
       DrawRegions();
       c = GetPix(R.r_cx>>1, R.r_dx);
       if (c < 240 && c > 0) SelectRegion(c);
       SWGC_on();
       }
    }

  asm { mov ax,3; int 0x10 }
  puts("MView - created 16.10.1997 by Martin DRAB (CZ) for ICP'97\nGood bye!");
  return 0;
  }
