/*
==============================================================================
		      WordUp Graphics Toolkit Version 5.0                     
			    Demonstration Program 53                          
									      
 VESA demonstration file. Any program which uses the WGT VESA library        
 requires the existence of a VESA driver. Most video card manufacturers      
 include software drivers with their installation diskettes. You can also    
 find drivers for most popular cards on a BBS.                               
									      
 VESA calls perform the same functions as their 320*200 equivalents in WGT.  
									      
 *** PROJECT ***                                                             
 This program requires the WGT5_WC.LIB and WVESA_WC.LIB files to be linked.  
									      
 *** DATA FILES ***                                                          
 WGT1.PCX and WGT2.PCX must be in your executable directory.      
							   WATCOM C++ VERSION 
==============================================================================
*/

#include <graph.h>
#include <wgt5.h>
#include <wgtvesa.h>

block wgt;                    /* Pointer to our first image to load */
block wgt2;                   /* Pointer to our second image to load */
block ptr;                    /* Temporary pointer */
color pal[256];               /* Our color palette */
int videomode[10];            /* Array to hold supported modes */
int totalmodes;               /* Total number of supported VESA modes */

char vstring[7][18] = { "640  x 350  x 256",
			"640  x 400  x 256", "640  x 480  x 256", 
			"800  x 600  x 256", "1024 x 768  x 256", 
			"1280 x 1024 x 256", "1600 x 1200 x 256" };



void getmodes (void)
{
  totalmodes = 0;               /* Start counter at 0 modes supported */

  /* Now find supported modes and add them to our array */
  if (wvesa_supported (V640x350))
  {
    videomode[totalmodes] = V640x350;
    totalmodes++;
  }
  if (wvesa_supported (V640x400))
  {
    videomode[totalmodes] = V640x400;
    totalmodes++;
  }
  if (wvesa_supported (V640x480))
  {
    videomode[totalmodes] = V640x480;
    totalmodes++;
  }
  if (wvesa_supported (V800x600))
  {
    videomode[totalmodes] = V800x600;
    totalmodes++;
  }
  if (wvesa_supported (V1024x768))
  {
    videomode[totalmodes] = V1024x768;
    totalmodes++;
  }
  if (wvesa_supported (V1280x1024))
  {
    videomode[totalmodes] = V1280x1024;
    totalmodes++;
  }
  if (wvesa_supported (V1600x1200))
  {
    videomode[totalmodes] = V1600x1200;
    totalmodes++;
  }
}


int which_string (int mode)
{
  /* This function simply returns a string number to display based on the
     highlighted video mode */
  switch (mode)
  {
    case V640x350   : return 0; 
    case V640x400   : return 1; 
    case V640x480   : return 2; 
    case V800x600   : return 3; 
    case V1024x768  : return 4; 
    case V1280x1024 : return 5; 
    case V1600x1200 : return 6; 
  }
  return 0;
}


int select_mode (void)
{
  int ctr;
  int done;
  int selected;
  struct rccoord endy;
  char ch;

  printf ("\nPress ENTER to selected highlighted mode, any other key advances highlight.\n");

  for (ctr = 0; ctr < totalmodes; ctr++)        /* Show supported modes */
  {
    _settextposition (13 + ctr, 1);
    _outtext (vstring[ which_string (videomode[ctr]) ]);
  }
  endy = _gettextposition ();

  selected = 0;
  done = 0;
  while (!done)
  {
    _settextcolor (12);                       /* Highlight string */
    _settextposition (13 + selected, 1);
    _outtext (vstring[ which_string (videomode[selected]) ]);
    ch = getch ();
    if (ch == 13)                               /* Abort when ENTER pressed */
      done = 1;
    else {
      while (kbhit ()) getch ();  
      _settextcolor (7);                    /* De-highlight previous */
      _settextposition (13 + selected, 1);
      _outtext (vstring[ which_string (videomode[selected]) ]);
      selected++;
      if (selected >= totalmodes)               /* Wrap around list */
	selected = 0;
    }
  }
  _settextposition (endy.row + 1, 1);

  return videomode[selected];           /* Return the selected mode */
}


void do_pixels (void)
{
  while (!kbhit ())              /* Random pixels */
  {
    wsetcolor (rand() % 256);
    wvesa_putpixel (rand() % VESAmode.XResolution, rand() % VESAmode.YResolution);
  }
  getch ();
}


void do_lines (void)
{
  while (!kbhit ())              /* Random lines */
  {
    wsetcolor (rand () % 256);
    wvesa_line (0, 0, rand () % VESAmode.XResolution, rand () % VESAmode.YResolution);
  }
  getch ();
}


void do_bars (void)
{
  while (!kbhit ())              /* Random bars */
  {
    wsetcolor (rand () % 256);
    wvesa_bar (rand () % VESAmode.XResolution, rand () % VESAmode.YResolution, 
	       rand () % VESAmode.XResolution, rand () % VESAmode.YResolution);
  }
  getch ();
}


void do_rectangles (void)
{
  while (!kbhit ())              /* Random rectangles */
  {
    wsetcolor (rand () % 256);
    wvesa_rectangle (rand () % VESAmode.XResolution, rand () % VESAmode.YResolution,
		     rand () % VESAmode.XResolution, rand () % VESAmode.YResolution);
  }
  getch ();
}


void do_text (void)
{
  wtexttransparent (TEXTFGBG);
  wtextbackground (0);
  while (!kbhit ())              /* Random rectangles */
  {
    wtextcolor (rand () % 256);
    wvesa_outtextxy (rand () % VESAmode.XResolution, rand () % VESAmode.YResolution, 
		     NULL, "VESA Text String");
  }
  getch ();
}


void do_blocks (void)
{
  while (!kbhit ())              /* Randomly paste blocks */
  {
    if (ptr == wgt)             /* Alternate between block 1 and block 2 */
      ptr = wgt2;
    else ptr = wgt;
    wvesa_putblock (rand () % VESAmode.XResolution, rand () % VESAmode.YResolution, 
		    ptr, NORMAL);
  }
  getch ();
}


void main (void)
{
  int oldmode;                  /* Video mode before program was started */
  int mymode = 0;               /* Selected video mode */

  oldmode = wgetmode ();        /* Preserve our original video mode */
  _clearscreen (_GCLEARSCREEN); /* Clear the screen */
  if (wvesa_detected ())        /* Look for VESA driver */
    printf ("SVGA detected.\n");
  else
  {
    printf ("SVGA support not found. Please check for VESA driver presence.\n");
    exit (1);
  }

  /* Display the video card maunfacturer's string */
  printf ("VESA version %x\n", VGA.VESAVersion);
  printf ("VIDEO CARD OEM STRING:\n%s\n", VGA.OEMStringPtr);
  if (VGA.VESAVersion >= 0x200)
  {
    printf ("OEM Software revision #%x\n", VGA.OemSoftwareRev);
    printf ("OEM Vendor Name: %s\n", VGA.OemVendorNamePtr);
    printf ("OEM Product Name: %s\n", VGA.OemProductNamePtr);
    printf ("OEM Product Revision: %s\n", VGA.OemProductRevPtr);
  }
    else printf ("\n\n\n\n");

  printf ("Memory on card: %dk\n", VGA.TotalMemory * 64);

  getmodes ();                           /* Find supported video modes */

  if (totalmodes == 0)
  {
    printf ("256 color SVGA modes not supported. Program aborted.\n");
    exit (1);
  }
  else
  {
    mymode = select_mode ();
  }    

  if (!wvesa_getmodeinfo (mymode))
    printf ("Mode detection failed.\n");
  else
  {
    printf ("\nMode %x selected.\n\n", mymode);
    printf ("X resolution : %5d\nY resolution : %5d\n", VESAmode.XResolution, VESAmode.YResolution);
    printf ("Banks: %d\n", VESAmode.NumberOfBanks);
    printf ("Window Granularity : %d\n", VESAmode.WinGranularity);
    printf ("Window size in Kb  : %d\n", VESAmode.WinSize);
    if (VESAmode.WinAAttributes & 1 == 0)
      printf("Window A not supported\n");
    else
      printf("Window A Segment   : %x\n", VESAmode.WinASegment);
    if (VESAmode.WinBAttributes & 1 == 0)
      printf("Window B not supported\n");
    else
      printf("Window B Segment   : %x\n", VESAmode.WinBSegment);
  }

  printf ("\n\nPRESS ANY KEY TO ENTER GRAPHICS MODE\n");
  getch ();

  vga256 ();
  if (!wvesa_init (mymode))
  {
    printf ("Unable to initialize graphics mode.\n");
    exit (1);
  }

  wgt = wloadpcx ("wgt1.pcx", pal);         /* Load our images */
  wgt2 = wloadpcx ("wgt2.pcx", pal);
  wsetpalette (0, 255, pal);

  do_pixels ();                         /* Perform our demo */
  wvesa_cls (15);
  do_blocks ();
  do_lines ();
  do_bars ();
  do_rectangles ();
  do_text ();
  wfreeblock (wgt);                     /* Free the images */
  wfreeblock (wgt2);
  
  wsetmode (oldmode);                    /* Return text mode */
}

