/*
 * V M O D E S
 *
 * Show how to run a program in the best
 * mode available for the hardware configuration it
 * finds when it starts execution.
 */

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <graph.h>
#include <math.h>

/*
 * Function prototypes.
 */
int SetBestColorGraphicsMode(void);

#define K_ESC           27
#define MODE_ERR        0

/*
 * Table of video modes and names.
 */
struct mode_st {
	int number;     /* internal mode number */
	char *name;     /* symbolic name */
	char *desc;     /* description */
} Mode[] = {
	0,      "_TEXTBW40",            "40x25 monochrome text",
	1,      "_TEXTC40",             "40x24 color text",
	2,      "_TEXTBW80",            "80x25 monochrome text",
	3,      "_TEXTC80",             "80x25 color text",
	4,      "_MRES4COLOR",          "320x200 4-color graphics",
	5,      "_MRESNOCOLOR",         "320x200 monochrome graphics",
	6,      "_HRESBW",              "640x200 monochrome",
	7,      "_TEXTMONO",            "80x25 monochrome text (MDA)",
	-1,     "",                     "(not supported)",
	-1,     "",                     "(not supported)",
	-1,     "",                     "(not supported)",
	-1,     "",                     "(not supported)",
	-1,     "",                     "(not supported)",
	13,     "_MRES16COLOR",         "320x200 16-color graphics",
	14,     "_HRES16COLOR",         "640x200 16-color graphics",
	15,     "_ERESNOCOLOR",         "640x350 monochrome graphics",
	16,     "_ERESCOLOR",           "640x350 color (4/16) graphics",
	17,     "_VRES2COLOR",          "640x480 monochrome graphics",
	18,     "_VRES16COLOR",         "640x480 16-color graphics",
	19,     "_MRES256COLOR",        "320x200 256-color graphics"
};

int
main(void)
{
	struct videoconfig vidconfig;   /* video config data */

	/*
	 * Try to set the highest available graphics
	 * resolution mode with the greatest number
	 * of colors.
	 */
	if (SetBestColorGraphicsMode() == MODE_ERR) {
		fprintf(stderr,
			"No medium resolution color support\n");
		exit (1);
	}

	/*
	 * Update video configuration members of
	 * vidconfig structure.
	 */
	_getvideoconfig(&vidconfig);

	/*
	 * Display information about the current video configuration.
	 */
	printf("\nVideo mode name: %s\n", Mode[vidconfig.mode].name);
	printf("[%s]\n\n", Mode[vidconfig.mode].desc);
	printf("Horizontal pixels = %d\n", vidconfig.numxpixels);
	printf("Vertical pixels = %d\n", vidconfig.numypixels);
	printf("Text rows = %d\n", vidconfig.numtextrows);
	printf("Text columns = %d\n", vidconfig.numtextcols);
	printf("Number of actual colors = %d\n",
		vidconfig.numcolors);
	printf("Bits per pixel = %d\n", vidconfig.bitsperpixel);
	printf("Video pages = %d\n", vidconfig.numvideopages);
	printf("Video memory size = %d KB\n", vidconfig.memory);

	/*
	 * Halt and wait for a keypress.
	 */
	fprintf(stderr, "\n\tPress a key...");
	if (getch() == '\0')
		getch();

	/*
	 * Restore the original video mode and
	 * return control to the operating system.
	 */
	_setvideomode(_DEFAULTMODE);
	return (0);
}


/*
 * SetBestColorGraphicsMode()
 *
 * Attempt to set the best available color graphics mode.
 */

int
SetBestColorGraphicsMode()
{
	int rc = MODE_ERR;      /* Assume the worst. */

	/*
	 * This routine assumes that
	 * resolution is more important than the number
	 * of actual colors.
	 */
	if (_setvideomode(_VRES16COLOR))
		rc = _VRES16COLOR;
	else if (_setvideomode(_ERESCOLOR))
		rc = _ERESCOLOR;
	else if (_setvideomode(_HRES16COLOR))
		rc = _HRES16COLOR;
	else if (_setvideomode(_MRES256COLOR))
		rc = _MRES256COLOR;
	else if (_setvideomode(_MRES16COLOR))
		rc = _MRES16COLOR;
	else if (_setvideomode(_MRES4COLOR))
		rc = _MRES4COLOR;

	/*
	 * Tell the calling function what was set.  A return
	 * code of MODE_ERR says we struck out -- no color.
	 */
	return (rc);
}
