/*
        Hardware Routines for MCGA 256 color mode plotting
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <math.h>
#include "fdesplot.h"
#include "fdesmenu.h"

#define MAXGUN 63
#define PI 3.14159265358979
/*
        Palette
*/
int pixel_max;                          /* largest pixel put value since last
                                           last 'set_palette' */
int color_shift;                        /* color shift used in 256 color mode */

int vcard_type;                         /* video card type
                                                0 = undefined
                                                1 = ast/paradise pro
                                                2 = orchid/genoa
                                        */
/*
popmenu vtype = {
        3,
        "AST/PARADISE", "GENOA/ORCHID", "Cancel"
        };

int vcard_type_check(void)      /* returns 0 if cancelled, mode# if successful */
{
int select;
        if (vcard_type == 0)
        {
                select = popup(100,100,&vtype,WHITE,BLUE);
		switch (select)
                {
                        case 1:                 /* ast/paradise */
                                vcard_type = 1;
                                return(0x5f);
                        case 2:                 /* genoa/orchid */
                                vcard_type = 2;
                                return(0x2e);
                        case 3:
                                return(0);
                }
	}
	else
	{
		switch (vcard_type)
                {
                        case 1:                 /* ast/paradise */
                                return(0x5f);
                        case 2:                 /* genoa/orchid */
                                return(0x2e);
                }
	}
	return(0);
}


typedef struct {
        unsigned char r,g,b;
        } rgb;

void set_palette(int quantize)
{
FILE *tempfile;
int i,j,level;
struct REGPACK regs;
rgb *palette;
float theta,tx,ty,compg,compr,fphi,sinphi,phi;

        if (quantize == 256)
        {
        gotoxy(1,1); printf("maximum quantization");
        }
        pixel_max = 0;
        palette = calloc(256,sizeof(rgb));
        regs.r_ax = 0x1017;             /* read block of DAC registers */
        regs.r_bx = 0;                  /* starting register */
        regs.r_cx = 256;                /* how many to read */
        regs.r_es = FP_SEG((void far *)palette);
        regs.r_dx = FP_OFF((void far *)palette);
        intr(0x10,&regs);

        if (quantize < 0)
        {
                quantize = -quantize;
		/* color wheel */
		/*
		   mapping from base { (1,0), (0,1) }
		   to base { (1,0), (cos(phi),sin(phi)) }
			   { red_vector, green_vector }
		*/
		phi = 2.0*PI/3.0;
		fphi = cos(phi)/sin(phi);
		sinphi = sin(phi);

                for (i=0; i<(quantize/3); i++)
                {
			theta = (i/(quantize/3.0 - 1))*2*PI/3.0;
			tx = 50.0*cos(theta);
			ty = 50.0*sin(theta);

			compr = tx - fphi*ty;
			compg = ty/sinphi;
                        j = (i + color_shift) % quantize;
                        palette[j+1].r = compr;
                        palette[j+1].g = compg;
                        palette[j+1].b = 0;
                        j = (i + quantize/3 + color_shift) % quantize;
                        palette[j+1].r = 0;
                        palette[j+1].g = compr;
                        palette[j+1].b = compg;
			j = (i + (2*quantize)/3 + color_shift) % quantize;
                        palette[j+1].r = compg;
                        palette[j+1].g = 0;
                        palette[j+1].b = compr;
                }
        }
        else
        {
                /* grey levels */
                for (i = 0; i<256; i++)   /* adjust DAC registers */
                {
                        if ((i%(quantize*2)) >= quantize)
                                level = quantize - 1 - (i%(quantize));
                        else level = (i%quantize);
                        palette[i].r = level*(64/quantize);
                        palette[i].g = level*(64/quantize);
                        palette[i].b = level*(64/quantize);

                }
	}

/*	tempfile = fopen("DAC","wt");
	for (i=0; i<256; i++)
	{
		fprintf(tempfile,"\nDAC %3d %3d %3d %3d",i,palette[i].r,
			palette[i].g,palette[i].b);
	}
	fclose(tempfile);
*/
        /* perform a 'set block of DAC registers' */
        regs.r_ax = 0x1012;             /* set block of DAC registers */
        regs.r_bx = 0;                  /* starting register */
        regs.r_cx = 256;                /* how many to read */
	regs.r_es = FP_SEG((void far *)palette);
	regs.r_dx = FP_OFF((void far *)palette);
        intr(0x10,&regs);
        free(palette);
}
/*
        Graphics Card initialize to 256 color mode (320x200)
*/
void init256(unsigned char mode)
{
struct REGPACK regs;

        /* set video mode */
        regs.r_ax = 0x0000 | mode;             /* function 0, mode 13h or 5fh */
        intr(0x10,&regs);

/*	set_palette(64); */
}

void putpixel256(int col, int row, unsigned char color)
{
struct REGPACK regs;
        if ((col > maxx) || (col < 0) || (row > maxy) || (row < 0)) return;
        regs.r_ax = 0x0c00 | color;
        regs.r_bx = 0;
        regs.r_cx = col;
        regs.r_dx = row;
        intr(0x10,&regs);

        pixel_max = max(pixel_max,color);
}

unsigned char getpixel256(int col, int row)
{
struct REGPACK regs;
        if ((col > maxx) || (col < 0) || (row > maxy) || (row < 0)) return(0);
        regs.r_ax = 0x0d00;
        regs.r_cx = col;
        regs.r_dx = row;
        intr(0x10,&regs);
        return(regs.r_ax & 0xff);
}
*/

