#undef FLAT_SHADING

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <GL/gl.h>
#include "gl42ogl.h"
#include "tk.h"
#include "insect.h"
#include "insectco.h"

GLushort ls = 0xaaaa;


unsigned char   halftone[] = {
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,

    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,

    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,

    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
    0xAA, 0xAA,    0xAA, 0xAA,
    0x55, 0x55,    0x55, 0x55,
};


GLfloat sdepth = 10.;
float   light[3],
        phi = PI / 4.0,
        theta = PI / 4.0;
GLfloat ctheta = -900, cphi, cvtheta, cvphi;

float fabso (float a );

/* Changes for ECLIPSE 8 bit machine */
/*  don't use 7 and 8 for appearances. These are the text standards */
unsigned short ECLIPSE8_RAMP[10] = {4, 5, 6, 8, 9, 10, 11, 12, 13, 14};
GLboolean is_8bit;
short savearray[384];

/** change for new window control */
float halfwinx, halfwiny;
long worgx, worgy;
long wsizex, wsizey;
long pikx, piky;

GLboolean follow;


float px, py;
float light[3];
float cx, cy, cz, cvx, cvy, cvz;
float dmr[6], fr[6];

GLfloat knee[6];
GLfloat hip_phi[6];
GLfloat hip_theta[6];
GLboolean legup[6];
float legx[6], legy[6];


enum {
    NOTHING,
    FORWARD,
    BACKWARD,
    LEFT,
    MIDDLE
};

short function;



/*  mymakerange  -- color ramp utilities		*/
void
mymakerange (unsigned short a, unsigned short b, GLubyte red1, GLubyte red2,
	GLubyte  green1, GLubyte green2, GLubyte blue1, GLubyte blue2)
{
    float   i;
    int     j;
    float   dr,
            dg,
            db;

    i = (float) (b - a);
    dr = (float) (red2 - red1) / i;
    dg = (float) (green2 - green1) / i;
    db = (float) (blue2 - blue1) / i;

    for (j = 0; j <= (int) i; j++)
	mapcolor ((unsigned short) j + a,
		(short) (dr * (float) j + red1),
		(short) (dg * (float) j + green1),
		(short) (db * (float) j + blue1));
/*	mapcolor ((unsigned short) j + a,
		(GLubyte) (dr * (float) j + red1),
		(GLubyte) (dg * (float) j + green1),
		(GLubyte) (db * (float) j + blue1));
*/
}


/*  Set up Eclipse 8 bit color ramp */


void
make_eclipse8_range(unsigned short e_ramp[], int red1, int red2,
                    int green1, int green2, int blue1, int blue2)
{
    int i;
    float rinc, ginc, binc;

    rinc = (float)(red2 - red1) / (float)ECLIPSE8_NCOLORS;
    ginc = (float)(green2 - green1) / (float)ECLIPSE8_NCOLORS;
    binc = (float)(blue2 - blue1) / (float)ECLIPSE8_NCOLORS;

    for (i = 0; i < ECLIPSE8_NCOLORS; i++) {
	mapcolor(e_ramp[i],
	    (short)(i * rinc + red1),
	    (short)(i * ginc + green1),
	    (short)(i * binc + blue1));
    }
}


/*  setupcolors  -- load color map		*/

/* Changed for ECLIPSE 8 bit machine */
void
setupcolors (void) {
    if (!is_8bit) {
	mapcolor (GRAY, 128, 128, 128);
	mapcolor (GRID, 128, 200, 250);
	mapcolor (SKYBLUE, 50, 50, 150);
	mymakerange (RAMPB5, RAMPE5, 125, 250, 125, 250, 0, 0);
	mymakerange (RAMPB4, RAMPE4, 100, 200, 125, 250, 0, 0);
	mymakerange (RAMPB3, RAMPE3, 75, 150, 125, 250, 0, 0);
	mymakerange (RAMPB2, RAMPE2, 50, 100, 125, 250, 0, 0);
	mymakerange (RAMPB, RAMPE, 25, 50, 125, 250, 0, 0);
    } else {
	mapcolor (ECLIPSE8_GRAY, 128, 128, 128);
	mapcolor (ECLIPSE8_GRID, 128, 200, 250);
	mapcolor (ECLIPSE8_SKYBLUE, 50, 50, 150);
/*
	mapcolor (BLACK, 0, 0, 0);
	mapcolor (COLORS, 255, 0, 0);
	mapcolor (COLOR1, 0, 255, 0);
	mapcolor (COLOR2, 255, 255, 0);
*/
	make_eclipse8_range(ECLIPSE8_RAMP, 25, 250, 125, 250, 0, 0);
    }
}


/**** New routines for ECLIPSE 8 bit machine */

/* reduces color index value to the lower 16 indices in the color table
	see ECLIPSE8_RAMP[] for which entries are used for ramp */

short
reduce_index (short c)
{
    c = c - RAMPB + 4;
    while (c > 13)
	c -= 10;
    if (c > 6)
	c++;
    return(c);
}


void
getcoords (void)
{
    pikx = getvaluator(MOUSEX);
    piky = getvaluator(MOUSEY);
    if (pikx <= worgx || pikx >= worgx + wsizex || 
	piky <= worgy || piky >= worgy + wsizey) {
	pikx = worgx + wsizex / 2 + 1;
	piky = worgy + wsizey / 2 + 1;
    }
}


static void
getMouseCoords (void) {
    int x, y;

	tkGetMouseLoc (&x, &y);
	pikx = x;
	piky = wsizey - y;
	if ( (pikx < 0) || (pikx > wsizex) ||
 	     (piky < 0) || (piky > wsizey) ) {
		pikx = wsizex / 2 + 1;
		piky = wsizey / 2 + 1;
	}
}


int
l05 (int i)
{
    if (i < 0)
	return (i + 6);
    if (i > 5)
	return (i - 6);
    return (i);
}


int
sgn (float i)
{
    if (i < 0)
	return (-1);
    if (i > 0)
	return (1);
    return (0);
}


static void
fixWindow (void) {
    halfwinx = (float)wsizex / 2.0;
    halfwiny = (float)wsizey / 2.0;

    glViewport (0, 0, wsizex, wsizey);
    glPopMatrix();
    glPushMatrix();
    gluPerspective (80, wsizex / (float) wsizey, 0.01, 131072);
}


/*  draw_shadow  -- draw halftone shape of insect onto the floor  */
void
draw_shadow (void) {
    int     leg;

    glPushMatrix ();
    glCallList (shadow);

	glEnable (GL_POLYGON_STIPPLE);
    glTranslatef (px, py, 1.0);
    glCallList (body_shadow);
    for (leg = 0; leg < 6; leg++) {
	glPushMatrix ();
/*
	glRotatef ((GLfloat) (-leg * 600), 0, 0, 1);
*/
	glRotatef ((GLfloat) (-leg * 60), 0, 0, 1);
	glTranslatef (0.0, 0.5, 0.0);
	glCallList (hip_shadow);
/*
	glRotatef (hip_phi[leg], 0, 0, 1);
	glRotatef (hip_theta[leg], 1, 0, 0);
*/
	glRotatef (hip_phi[leg] / 10, 0, 0, 1);
	glRotatef (hip_theta[leg]/10, 1, 0, 0);
	glCallList (thigh_shadow);
	glCallList (kneeball_shadow);
	glTranslatef (0.0, 1.0, 0.0);
/*
	glRotatef (knee[leg], 1, 0, 0);
*/
	glRotatef (knee[leg]/10, 1, 0, 0);
	glCallList (shin_shadow);
	glPopMatrix ();
    }

	glDisable (GL_POLYGON_STIPPLE);
    glPopMatrix ();
}


/*  draw_hind  -- draw a rear leg.  First draw hip, then shin, then thigh
	and knee joint			*/
void
draw_hind (int leg)
{
    glPushMatrix ();
/*
    glRotatef ((GLfloat) (-leg * 600), 0, 0, 1);
*/
    glRotatef ((GLfloat) (-leg * 60), 0, 0, 1);
    glTranslatef (0.0, 0.5, 0.0);
    glCallList (hip[leg]);
/*
    glRotatef (hip_phi[leg], 0, 0, 1);
    glRotatef (hip_theta[leg], 1, 0, 0);
*/
    glRotatef (hip_phi[leg]/10, 0, 0, 1);
    glRotatef (hip_theta[leg]/10, 1, 0, 0);
    glPushMatrix ();		/* draw thigh */
    glTranslatef (0.0, 1.0, 0.0);
/*
    glRotatef (knee[leg], 1, 0, 0);
*/
    glRotatef (knee[leg]/10, 1, 0, 0);
    glCallList (shin[leg]);
    glPopMatrix ();
    if (cz < -5.0) {
	glCallList (kneeball[leg]);
	glCallList (thigh[leg]);
    }
    else {
	glCallList (kneeball[leg]);
	glCallList (thigh[leg]);
    }
    glPopMatrix ();
}


/*  draw_fore  -- draw a front leg.  First draw hip, then thigh,
	knee joint and finally shin		*/

void
draw_fore (int leg)
{
    glPushMatrix ();
/*
    glRotatef ((GLfloat) (-leg * 600), 0, 0, 1);
*/
    glRotatef ((GLfloat) (-leg * 60), 0, 0, 1);
    glTranslatef (0.0, 0.5, 0.0);
    glCallList (hip[leg]);
/*
    glRotatef (hip_phi[leg], 0, 0, 1);
    glRotatef (hip_theta[leg], 1, 0, 0);
*/
    glRotatef (hip_phi[leg]/10, 0, 0, 1);
    glRotatef (hip_theta[leg]/10, 1, 0, 0);
    glCallList (thigh[leg]);
    glCallList (kneeball[leg]);
    glTranslatef (0.0, 1.0, 0.0);
/*
    glRotatef (knee[leg], 1, 0, 0);
*/
    glRotatef (knee[leg]/10, 1, 0, 0);
    glCallList (shin[leg]);
    glPopMatrix ();
}


/*  draw_insect  -- draw rear legs, body and forelegs of insect 
	the order of drawing the objects is important to 
	insure proper hidden surface elimination -- painter's algorithm	*/
void
draw_insect (void) {
    GLfloat a;
    float   o;
    int     order;

    o = atan2 (cy + py, cx + px) + PI - (PI / 3.0);
    order = l05 ((int) integer (o / (PI / 3.0)));
    glPushMatrix ();		/* world */
    glTranslatef (px, py, 1.0);
    draw_hind (l05 (3 - order));
    draw_hind (l05 (4 - order));
    draw_hind (l05 (2 - order));
    glCallList (body);
    draw_fore (l05 (5 - order));
    draw_fore (l05 (1 - order));
    draw_fore (l05 (0 - order));
    glPopMatrix ();
}


/*  spin_scene  -- poll input devices, keyboard and mouse
	move eye position based upon user input			*/

void
spin_scene (void) {
    float   sin1,
            cos1,
            sin2,
            cos2,
            t;
    int     mx,
            my;


    /* big change to keep movement relative to window */
    /* check if still in window x and y are globals - see getcoords */
/*
    getcoords ();
    mx = 64 * ((pikx - worgx) - (wsizex / 2)) / wsizex;
    my = 64 * ((piky - worgy) - (wsizey / 2)) / wsizey;
*/

    getMouseCoords();
    mx = 64 * (pikx - (wsizex/2)) / wsizex;
    my = 64 * (piky - (wsizey/2)) / wsizey;


/*
    mx = (getvaluator (MOUSEX) - 640) / 16;
    my = (getvaluator (MOUSEY) - 512) / 16;
*/

    switch (function) {
      case BACKWARD:
	gl_sincos (ctheta, &sin1, &cos1);
	gl_sincos (cphi, &sin2, &cos2);
	cvz -= cos1;
	cvx -= sin2 * sin1;
	cvy -= cos2 * sin1;
	function = NOTHING;
        break;
      case FORWARD:
	gl_sincos (ctheta, &sin1, &cos1);
	gl_sincos (cphi, &sin2, &cos2);
	cvz += cos1;
	cvx += sin2 * sin1;
	cvy += cos2 * sin1;
	function = NOTHING;
	break;
      case LEFT:
	cvz = (float) - my;
	gl_sincos (cphi, &sin1, &cos1);
	cvx = cos1 * (float) (-mx);
	cvy = -sin1 * (float) (-mx);
	break;
      default:
	cvx = cvx * 0.7;
	cvy = cvy * 0.7;
	cvz = cvz * 0.7;
	break;
    }

    if (function == MIDDLE) {
	cvtheta = my;
	cvphi = mx;
    }
    else {
	cvtheta += -cvtheta / 4;
	if ((cvtheta < 4) && (cvtheta > -4))
	    cvtheta = 0;
	cvphi += -cvphi / 4;
	if ((cvphi < 4) && (cvphi > -4))
	    cvphi = 0;
	if (function != LEFT) function = NOTHING;
    }

    cx += cvx * 0.0078125;
    cy += cvy * 0.0078125;
    if (cz > 0.0) {
	cz = 0.0;
	cvz = 0.0;
    }
    else
	cz += cvz * 0.0078125;
    ctheta += cvtheta;
    cphi += cvphi;
}


GLfloat degrees (float a)
{
    return ((GLfloat) (a * 1800.0 / PI));
}


void
getstuff (void) {
    int     x,
            y,
            i;
    int     tr;

    legup[0] = GL_FALSE;
    legup[2] = GL_FALSE;
    legup[4] = GL_FALSE;
    legup[1] = GL_TRUE;
    legup[3] = GL_TRUE;
    legup[5] = GL_TRUE;

    px = 0.0;
    py = 0.0;
    for (i = 0; i < 6; i++) {
	legx[i] = 30.0 / 2.0 + (float) i;
	legy[i] = 30.0 / 2.0 + (float) i;
    }
}


void
dolegs (void) {
    int     i;
    float   r,
            l,
            gx,
            gy,
            k,
            t,
            a,
            ux,
            uy;
    int     leg,
            tr;

    for (leg = 0; leg < 6; leg++) {
	gx = legx[leg] - 30.0 / 2.0;
	gy = legy[leg] - 30.0 / 2.0;
	ux = gx / (30.0 / 2.0);
	uy = gy / (30.0 / 2.0);

	switch (leg) {
	    case 0: 
		gx += 0.0;
		gy += 30.0;
		break;
	    case 1: 
		gx += (30.0 * 0.8660254);
		gy += (30.0 * 0.5);
		break;
	    case 2: 
		gx += (30.0 * 0.8660254);
		gy += (30.0 * -0.5);
		break;
	    case 3: 
		gx += 0.0;
		gy += -30.0;
		break;
	    case 4: 
		gx += (30.0 * -0.8660254);
		gy += (30.0 * -0.5);;
		break;
	    case 5: 
		gx += (30.0 * -0.8660254);
		gy += (30.0 * 0.5);
		break;
	}
	r = sqrt ((gx * gx) + (gy * gy)) / 30.0;
	l = sqrt (1.0 + (r * r));
	k = acos ((5.0 - (l * l)) / 4.0);

	knee[leg] = (GLfloat) degrees (k);

	t = (2.0 * sin (k)) / l;
	if (t > 1.0)
	    t = 1.0;

	a = asin (t);
	if (l < 1.7320508)
	    a = PI - a;

	hip_theta[leg] =
	    (GLfloat) (degrees (a - atan2 (1.0, r)));

	if (gx == 0.0) {
	    hip_phi[leg] = (GLfloat) (900 * sgn (gy));
	}
	else {
	    hip_phi[leg] = (GLfloat) (degrees (atan2 (gy, gx)));
	}
	hip_phi[leg] += (-900 + 600 * leg);

	if (legup[leg]) {
	    hip_theta[leg] += (GLfloat)
		(200.0 * ((fr[leg] / 2.0) - fabso (dmr[leg] - (fr[leg] / 2.0))));
	}
    }
}


void
move_insect (void) {
    register int    i;
    register float  mx,
                    my,
                    vx,
                    vy,
                    dx,
                    dy,
                    dr,
                    lx,
                    ly,
                    lr,
                    dmx,
                    dmy;
    float   s,
            c;

/*  mx = (float) getvaluator (MOUSEX) / 640.0 - 1.0;
    my = (float) getvaluator (MOUSEY) / 512.0 - 1.0;
*/

/* changed to keep input within the window.
 x and y are globals - see getcoords */
/*
    getcoords ();
    mx = ((float)pikx - (float)worgx) / halfwinx - 1.0;
    my = ((float)piky - (float)worgy) / halfwiny - 1.0;
*/
	getMouseCoords();
	mx = pikx / halfwinx - 1.0; 
	my = piky / halfwiny - 1.0;



    gl_sincos (cphi, &s, &c);
    dx = mx * c + my * s;
    dy = -mx * s + my * c;
    mx = dx;
    my = dy;

    px += mx / (float) (RES);
    py += my / (float) (RES);

    if (follow) {
	cx -= mx / (float) (RES);
	cy -= my / (float) (RES);
    }

    dr = sqrt (mx * mx + my * my);
    dx = mx / dr;
    dy = my / dr;

    for (i = 0; i < 6; i++) {
	lx = legx[i] - (float) (RES / 2);
	ly = legy[i] - (float) (RES / 2);
	lr = (float) (RES / 2);
	lx = lx / lr;
	ly = ly / lr;
	dmx = (dx - lx);
	dmy = (dy - ly);
	dmr[i] = sqrt (dmx * dmx + dmy * dmy);
	if (legup[i]) {
	    dmx = 3 * dr * dmx / dmr[i];
	    dmy = 3 * dr * dmy / dmr[i];
	    legx[i] += dmx;
	    legy[i] += dmy;
	    if ((dmr[i]) < 0.15) {
		legup[i] = GL_FALSE;
	    }
	}
	else {
	    legx[i] -= mx;
	    legy[i] -= my;

	    if (!legup[l05 (i - 1)] && !legup[l05 (i + 1)] &&
		    (dmr[i] > REACH) &&
		    ((lx * dx + ly * dy) < 0.0)) {
		legup[i] = GL_TRUE;
		fr[i] = dmr[i];
		legx[i] += dmx;
		legy[i] += dmy;
	    }
	}
    }
}


void
rotate60 (char c, int n, GLfloat a[][3])
{
    int     i,
            j,
            l;
    float   nx,
            ny;

    switch (c) {
	case 'z': 
	    i = 0;
	    j = 1;
	    break;
	case 'y': 
	    i = 2;
	    j = 0;
	    break;
	case 'x': 
	    i = 1;
	    j = 2;
	    break;
    };
    for (l = 0; l < n; l++) {
	nx = a[l][i] * COS60 - a[l][j] * SIN60;
	ny = a[l][i] * SIN60 + a[l][j] * COS60;
	a[l][i] = nx;
	a[l][j] = ny;
    }
}


void
getpolycolor (int p, float pts[][3])
{
    float   norm[3];
    float   v1[3],
            v2[3],
            cons;
    int     i,
            get;
    float   c;

    for (i = 0; i < 3; i++)
	norm[i] = 0.0;
    i = 0;
    get = 1;
    i = 1;
    v1[0] = pts[1][0] - pts[0][0];
    v1[1] = pts[1][1] - pts[0][1];
    v1[2] = pts[1][2] - pts[0][2];

    v2[0] = pts[2][0] - pts[0][0];
    v2[1] = pts[2][1] - pts[0][1];
    v2[2] = pts[2][2] - pts[0][2];

    norm[0] = v1[1] * v2[2] - v1[2] * v2[1];
    norm[1] = v1[2] * v2[0] - v1[0] * v2[2];
    norm[2] = v1[0] * v2[1] - v1[1] * v2[0];

    cons = sqrt ((norm[0] * norm[0]) +
	    (norm[1] * norm[1]) + (norm[2] * norm[2]));
    for (i = 0; i < 3; i++)
	norm[i] = norm[i] / cons;

    c = dot (norm, light);
    if (c < 0.0)
	c = 0.0;
    if (c > 1.0)
	c = 1.0;
    switch (p) {
	case 0: 
	    c = (float) (RAMPE - RAMPB) * c + (float) (RAMPB);
            if (((unsigned short) c) > RAMPE) c = (float) RAMPE;
#ifdef FLAT_SHADING
	    c = COLOR1;
#endif
	    break;
	case 1: 
	    c = (float) (RAMPE2 - RAMPB2) * c + (float) (RAMPB2);
            if (((unsigned short) c) > RAMPE2) c = (float) RAMPE2;
#ifdef FLAT_SHADING
    	    c = COLOR2;
#endif
	    break;
	case 2: 
	    c = (float) (RAMPE3 - RAMPB3) * c + (float) (RAMPB3);
            if (((unsigned short) c) > RAMPE3) c = (float) RAMPE3;
#ifdef FLAT_SHADING
    	    c = COLOR2;
#endif
	    break;
	case 3: 
	    c = (float) (RAMPE4 - RAMPB4) * c + (float) (RAMPB4);
            if (((unsigned short) c) > RAMPE4) c = (float) RAMPE4;
#ifdef FLAT_SHADING
    	    c = COLOR2;
#endif
	    break;
	case 4: 
	    c = (float) (RAMPE5 - RAMPB5) * c + (float) (RAMPB5);
            if (((unsigned short) c) > RAMPE5) c = (float) RAMPE5;
#ifdef FLAT_SHADING
    	    c = COLOR2;
#endif
	    break;
    }

    /* Changed for 8 bit ECLIPSE machine */
    if (is_8bit)
	c = (float)reduce_index((int)c);
    glIndexi (c);	
}


GLboolean
lit (int p, float pts[][3])
{
    float   norm[3];
    float   v1[3],
            v2[3],
            cons;
    int     i,
            get;
    float   c;

    for (i = 0; i < 3; i++)
	norm[i] = 0.0;
    i = 0;
    get = 1;
    i = 1;
    v1[0] = pts[1][0] - pts[0][0];
    v1[1] = pts[1][1] - pts[0][1];
    v1[2] = pts[1][2] - pts[0][2];

    v2[0] = pts[2][0] - pts[0][0];
    v2[1] = pts[2][1] - pts[0][1];
    v2[2] = pts[2][2] - pts[0][2];

    norm[0] = v1[1] * v2[2] - v1[2] * v2[1];
    norm[1] = v1[2] * v2[0] - v1[0] * v2[2];
    norm[2] = v1[0] * v2[1] - v1[1] * v2[0];

    cons = sqrt ((norm[0] * norm[0]) +
	    (norm[1] * norm[1]) + (norm[2] * norm[2]));
    for (i = 0; i < 3; i++)
	norm[i] = norm[i] / cons;

    c = dot (norm, light);
    return (c > 0.0);
}


float   dot (float vec1[3], float vec2[3])
{
    float   xx;
    xx = (vec1[1] * vec2[1])
	+ (vec1[2] * vec2[2])
	+ (vec1[0] * vec2[0]);
    return ((float) xx);
}


void 
getlightvector (void) {
    float   f;
    light[2] = cos (theta);
    f = sin (theta);
    light[1] = -sin (phi) * f;
    light[0] = -cos (phi) * f;
}


float   integer (float x)
{
    if (x < 0.0)
	x -= 1.0;
    x = (float) (int) x;
    return (x);
}


float   frac (float x)
{
    return (x - integer (x));
}


float
fabso (float x)
{
    if (x < 0.0)
	return (-x);
    else
	return (x);
}


void
drawAll (void) {
   /* new for ECLIPSE 8 bit version */
   if (is_8bit)
      glClearIndex (ECLIPSE8_SKYBLUE);
   else
      glClearIndex (SKYBLUE);

   glClear (GL_COLOR_BUFFER_BIT);
   glPushMatrix();
   doViewit();
   glCallList (screen);
   draw_shadow();
   draw_insect();
   glPopMatrix();
}


static void Reshape(int width, int height)
{

      wsizex = width;
      wsizey = height;
      fixWindow();
}

static GLenum Key(int key, GLenum mask)
{
      switch (key) {
        case TK_ESCAPE:
          tkQuit();
          break;
	case TK_A:
	case TK_a:
	  function = FORWARD;
	  break;
	case TK_Z:
	case TK_z:
	  function = BACKWARD;
	  break;
	case TK_F:
	case TK_f:
	  follow = !follow;
	  break;
        default:
          return GL_FALSE;
      }
      return GL_TRUE;
}

static GLenum MouseUp(int mouseX, int mouseY, GLenum button)
{
	switch (button) {
	  case TK_LEFTBUTTON:
	    function = NOTHING;
	    break;
	  case TK_MIDDLEBUTTON:
	    function = NOTHING;
	    break;
	  default:
	    return GL_FALSE;
	}
      return GL_TRUE;
}

static GLenum MouseDown(int mouseX, int mouseY, GLenum button)
{

	switch (button) {
	  case TK_LEFTBUTTON:
	    function = LEFT;
	    break;
	  case TK_MIDDLEBUTTON:
	    function = MIDDLE;
	    break;
	  default:
	    return GL_FALSE;
	}
      return GL_TRUE;
}

static void animate (void) {
      spin_scene();
      move_insect();
      dolegs();
      drawAll();
      tkSwapBuffers();
}



/*	main routine -- handle tokens of window manager
		-- display shadow and insect
*/

void
main (int argc, char *argv[]) {
    int     i,
            j,
            k;
    short   dev,
            val;
    long    nplanes;
    GLboolean attached;


    follow = GL_TRUE;
    wsizex = 500;
    wsizey = 400;
    worgx = 252;
    worgy = 184;

    tkInitPosition(0, 0, wsizex, wsizey);

    tkInitDisplayMode(TK_INDEX|TK_DOUBLE|TK_DIRECT|TK_DEPTH16);

    if (tkInitWindow("Insect") == GL_FALSE) {
        tkQuit();
    }

    glPolygonStipple ((unsigned char *) halftone);
    glShadeModel(GL_FLAT);

    getlightvector ();

/* Changes for ECLIPSE 8 bit machine */



/*
 * Machines with enough bitplanes will use colormap entries CMAPSTART
 * to CMAPSTART+127.  If the machine doesn't have enough bitplanes,
 * only colors 0 to 15 will be used (it is assumed that all machines
 * have at least 4 bitplanes in colormap double-buffered mode).
 */
#ifdef ECLIPSE
    nplanes = glGetI(GD_BITS_NORM_DBL_CMODE);
    /* save color map in savearray */
    if ((1<<nplanes) > (CMAPSTART+127)) {
	is_8bit = GL_FALSE;
    }
    else {
	is_8bit = GL_TRUE;
    }
#else
	nplanes = 4;
	is_8bit = GL_TRUE;
#endif


    setupcolors ();
/* initialize transformation stuff */
    cx = 0.0;
    cy = 10.0;
    cz = -2.0;
    cvx = cvy = cvz = 0.0;
    ctheta = -900;
    cphi = 0;
    cvtheta = cvphi = 0.0;
    function = NOTHING;

    glPushMatrix();

    fixWindow();
    createobjects ();
    getstuff ();
    spin_scene ();
    move_insect ();
    dolegs ();

    tkExposeFunc(Reshape);
    tkReshapeFunc(Reshape);
    tkKeyDownFunc(Key);
    tkMouseDownFunc(MouseDown);
    tkMouseUpFunc(MouseUp);
    tkIdleFunc(animate);
    tkExec();

    glPopMatrix();
}