/*
==============================================================================
		      WordUp Graphics Toolkit Version 4.5
			     Demonstration Program 67

  This scrolling example shows how to draw directly on the scrolling window.
  It makes a reduced size map by creating 1x1 tiles with the most common
  color found in each large tile.  This small window is displayed at the top
  right corner, overtop the main scrolling window.  As well, a cross shows
  the current viewing position in both windows.

 *** PROJECT ***
 This program requires the WGT45.LIB and WGTSCROL.LIB files to be linked.

 *** DATA FILES ***
 MUN.WMP, MUNCHMAP.SPR, MUNCHKIN.SPR
==============================================================================
*/
#include <dos.h>
#include <alloc.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>

#include <wgt45.h>
#include <wgtscrol.h>

typedef short tiletypes[256];

short movex, movey;
short lookx, looky;

wgtmap munchmap;                   /* our world map */
tiletypes munchtypes;

#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define CTRL 29
#define ESC 1

#define TILE_SIZE 16

#define MAINWIN 0
#define MINIWIN 1
#define NUM_TILE 256
#define NUM_OBJ 256
#define NUM_SPR 100

color palette[256];                /* our palette of colours */

block munchtiles[NUM_TILE];        /* our blocks for the map */
block minitiles[NUM_TILE];
block munchsprites[NUM_SPR];       /* our sprites */
scrollsprite munchobj[NUM_OBJ];

short windx, windy;
short mwindx, mwindy;

short i;

short oldmode;


short colfreq[256];

void make_mini_tiles (block *tiles)
/* ---------------------------------------------------------------------------
   (Originally written by Barry Egerter for the WGT Map Maker)
   Scan through 256 color palette and our tiles to determine the best color
   number to use for tile representation in the reduced map image.

   I simply find the most frequently occuring color in a given tile, and
   store it in an array. Whenever I want to draw that tile on the small map
   representation, use the color number given in the array.
--------------------------------------------------------------------------- */
{
  unsigned short num;
  unsigned short maxctr;
  unsigned short mostfreq;
  unsigned short pixelctr;
  block tempbl;

  for (num = 0; num < NUM_TILE; num++)
  /* Search through each tile */
  {
    if (tiles[num] != NULL)
     /* The tile exists */
    {
      for (pixelctr = 0; pixelctr < 256; pixelctr++)
	 colfreq[pixelctr] = 0;
      /* Clear out the frequency table */

      tempbl = tiles[num];
      maxctr = wgetblockwidth (tempbl) * wgetblockheight (tempbl);
      /* Holds the number of pixels in the tile */

      tempbl += 4;                            /* Make ptr to tile */
      pixelctr = 0;                             /* set ctr to 0 */
      do {
	colfreq[*tempbl]++;                     /* Update frequency table */
	tempbl++;
	pixelctr++;
      } while (pixelctr < maxctr);

      mostfreq = 0;
      for (pixelctr = 0; pixelctr < 256; pixelctr++)    /* Scan for most common */
	if (colfreq[pixelctr] >= colfreq[mostfreq])
	  mostfreq = pixelctr;

      wsetcolor (mostfreq);
      wputpixel (0, 0);
      minitiles[num] = wnewblock (0, 0, 0, 0);
      /* Draw a single pixel and make a new mini tile */
    }
   else
     minitiles[num] = NULL;
  }

}




void main (void)
{
int x, y;

  oldmode = wgetmode ();
  if (!vgadetected ())
  {
    printf ("VGA is required to run this program...");
    exit (1);
  }

  printf ("WGT Example #67\n\n");
  printf ("This scrolling example shows how to draw directly on the scrolling window.\n");
  printf ("It makes a reduced size map by creating 1x1 tiles with the most common\n");
  printf ("color found in each large tile.  This small window is displayed at the top\n");
  printf ("right corner, overtop the main scrolling window.  As well, a cross shows\n");
  printf ("the current viewing position in both windows.\n");

  printf ("\n\nWindow Width (2-20):");
  scanf ("%i", &windx);
  printf ("\nWindow Height (2-12):");
  scanf ("%i", &windy);

  mwindx = 32;
  mwindy = 32;


  vga256 ();
  wloadsprites (palette, "munchmap.spr", munchtiles, 0, NUM_TILE - 1);
  wloadsprites (palette, "munchkin.spr", munchsprites, 0, NUM_SPR - 1);
  wsetpalette (0, 255, palette);

  make_mini_tiles (munchtiles);

  winitscroll (MAINWIN, NORMAL, - 1, windx, windy, munchtiles);
  munchmap = wloadmap (MAINWIN, "mun.wmp", munchtypes, munchobj);

  winitscroll (MINIWIN, NORMAL, - 1, mwindx, mwindy, minitiles);
  wcopymap (0, 1);

  wnormscreen ();
  wcls (0);

  wshowwindow (MAINWIN, 0, 0);
  wshowwindow (MINIWIN, 0, 0);
  lookx = 0;
  looky = 0;

  installkbd ();

  do {

    movex = 0;
    movey = 0;
    
    if (kbdon[LEFT])
      movex = -8;
    else if (kbdon[RIGHT])
      movex = 8;
    if (kbdon[UP])
      movey = -8;
    else if (kbdon[DOWN])
      movey = 8;

    /* Lookx and looky are the coordinates of a moving object on the world */
    /* The following code finds the difference between the current world  
       coordinates and this object, and scrolls to center the object within
       the window. */

    lookx += movex;
    looky += movey;

    if (lookx < 0)
      lookx = 0;
    else if (lookx > mapwidth[MAINWIN] * 16)
      lookx = mapwidth[MAINWIN] * 16;
    
    if (looky < 0)
      looky = 0;
    else if (looky > mapheight[MAINWIN] * 16)
      looky = mapheight[MAINWIN] * 16;
    

    /* Move the large window */
    movex = lookx - worldx[MAINWIN] - windowmaxx[MAINWIN]/2 - 1;
    movey = looky - worldy[MAINWIN] - windowmaxy[MAINWIN]/2 - 1;
    wscrollwindow (MAINWIN, movex, movey);

    /* Move the small window.  Divide the movements by 16 since the tiles
       are 1 pixel instead of 16. */
    x = (lookx+1) / 16;
    y = (looky+1) / 16;
    movex = x - worldx[MINIWIN] - windowmaxx[MINIWIN]/2;
    movey = y - worldy[MINIWIN] - windowmaxy[MINIWIN]/2;
    wscrollwindow (MINIWIN, movex, movey);

    wshowobjects (MAINWIN, 1, NUM_OBJ - 1, munchsprites, munchobj);

    
    /* Now we have two tiled maps shown in scrollblocks 0 and 1.
       I want a cross to show the location of (lookx, looky) on both
       maps.  First draw the cross on the mini map: */
    wsetscreen (scrollblock[MINIWIN]);
    /* Set drawing to the mini map */
    
    /* Get the screen coordinates of the cross */
    x = wscreen_coordx (MINIWIN, x);    
    y = wscreen_coordy (MINIWIN, y);    

    wsetcolor (1);
    wline (x-1, y, x+1, y);  /* Draw a little cross */
    wline (x, y-1, x, y+1);

    /* Now draw on the large map. */
    wsetscreen (scrollblock[MAINWIN]);

    x = wscreen_coordx (MAINWIN, lookx);    
    y = wscreen_coordy (MAINWIN, looky);    
    
    wline (x-5, y, x+5, y);  /* Draw a large cross */
    wline (x, y-5, x, y+5);
    
    /* Paste the mini map over the large map, in the top right corner.
       Leaves 5 pixels from the top right edge. */
    wputblock (windx * 16 - mwindx - 5, 5, scrollblock[MINIWIN], NORMAL);
    
    /* Print out the coordinates of the cross */
    wtextcolor (1);
    wgtprintf (0, 0, NULL, "X: %hi  Y:%hi", lookx, looky);

    /* Return to the visual page and show the final image */
    wnormscreen ();
    wretrace ();
    wputblock (0, 0, scrollblock[MAINWIN], NORMAL);

  } while  (kbdon[ESC] != 1);          /* until ESC key is pressed */
  
  uninstallkbd ();
  
  wendscroll (MAINWIN);
  wendscroll (MINIWIN);
  wfreesprites (munchtiles, 0, NUM_TILE - 1);
  wfreesprites (munchsprites, 0, NUM_SPR - 1);
  wfreemap (munchmap);
  wsetmode (oldmode);
}


