/*
 * SoccerBall.c
 * Tony Bybell
 * CSE 418
 * Tue Jan 30 00:27:00 EST 1996
 *
 * This is a _simple_ little example of how to go about implementing a
 * hidden surface algorithm.  Define your faces in a clockwise manner and
 * the routine will do the rest.  This only works on _convex_ objects.
 * There is no sanity checking, so any gurus you generate are your own
 * fault...
 *
 * compile with: gcc filename.c -L/usr/X11/lib -lX11
 * gcc -I/depot/x11r5/include -o x x.c -L/depot/x11r5/lib -lXm -lXt -lX11 -lm
 * ...if you're in Pond's 111 Sun lab.  
 */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

/*------------------------------------------------------------------ */
#ifndef ITIMER_REAL              /* fixes compiles on suns and linux */
#define ITIMER_REAL     0
#define ITIMER_VIRTUAL  1
#define ITIMER_PROF     2

struct timeval {
        long    tv_sec;         /* seconds */
        long    tv_usec;        /* and microseconds */
};


struct  itimerval {
        struct  timeval it_interval;    /* timer interval */
        struct  timeval it_value;       /* current value */
};
#endif
/*------------------------------------------------------------------ */

#define XWIN_SIZE 320
#define YWIN_SIZE 200


/*
 * Those Lovely Prototypes...
 */
void Rotate(short *,short *,short,short,short,short,short,short);
void DrawObject(short,short,short,short,short,short);


/*
 * A Unique Struct...
 */
struct Object {
        short *Faces;
        short *Points;
        };


/* 
 * X Globals...
 */
Display *display;
Window window;
int screen;
GC clear, background;
GC pixor, pixcopy, pixor2, pixcopy2;
Pixmap buffer;


/*
 * Color stuff...
 */
Colormap colors;
void setc(unsigned long pixval, unsigned long r, unsigned long g,
           unsigned long b) {

XColor palette;

    palette.pixel=pixval;
    palette.red=r;
    palette.green=g;
    palette.blue=b;
    palette.flags=DoRed|DoGreen|DoBlue;
    
XStoreColor(display,colors,&palette);
}


/*
 * Multi-Purpose Sine/Cosine lookup table...I know, what's a .h file? =)
 * See implementation in Rotate()
 */
const signed short sincos[]={
        0x0000,0x0001,0x0003,0x0004,0x0006,0x0007,0x0009,0x000A,
        0x000C,0x000E,0x000F,0x0011,0x0012,0x0014,0x0015,0x0017,
        0x0019,0x001A,0x001C,0x001D,0x001F,0x0020,0x0022,0x0024,
        0x0025,0x0027,0x0028,0x002A,0x002B,0x002D,0x002E,0x0030,
        0x0031,0x0033,0x0035,0x0036,0x0038,0x0039,0x003B,0x003C,
        0x003E,0x003F,0x0041,0x0042,0x0044,0x0045,0x0047,0x0048,
        0x004A,0x004B,0x004D,0x004E,0x0050,0x0051,0x0053,0x0054,
        0x0056,0x0057,0x0059,0x005A,0x005C,0x005D,0x005F,0x0060,
        0x0061,0x0063,0x0064,0x0066,0x0067,0x0069,0x006A,0x006C,
        0x006D,0x006E,0x0070,0x0071,0x0073,0x0074,0x0075,0x0077,
        0x0078,0x007A,0x007B,0x007C,0x007E,0x007F,0x0080,0x0082,
        0x0083,0x0084,0x0086,0x0087,0x0088,0x008A,0x008B,0x008C,
        0x008E,0x008F,0x0090,0x0092,0x0093,0x0094,0x0095,0x0097,
        0x0098,0x0099,0x009B,0x009C,0x009D,0x009E,0x009F,0x00A1,
        0x00A2,0x00A3,0x00A4,0x00A6,0x00A7,0x00A8,0x00A9,0x00AA,
        0x00AB,0x00AD,0x00AE,0x00AF,0x00B0,0x00B1,0x00B2,0x00B3,
        0x00B5,0x00B6,0x00B7,0x00B8,0x00B9,0x00BA,0x00BB,0x00BC,
        0x00BD,0x00BE,0x00BF,0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,
        0x00C5,0x00C6,0x00C7,0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,
        0x00CD,0x00CE,0x00CF,0x00D0,0x00D1,0x00D2,0x00D3,0x00D3,
        0x00D4,0x00D5,0x00D6,0x00D7,0x00D8,0x00D9,0x00D9,0x00DA,
        0x00DB,0x00DC,0x00DD,0x00DD,0x00DE,0x00DF,0x00E0,0x00E1,
        0x00E1,0x00E2,0x00E3,0x00E3,0x00E4,0x00E5,0x00E6,0x00E6,
        0x00E7,0x00E8,0x00E8,0x00E9,0x00EA,0x00EA,0x00EB,0x00EB,
        0x00EC,0x00ED,0x00ED,0x00EE,0x00EE,0x00EF,0x00EF,0x00F0,
        0x00F1,0x00F1,0x00F2,0x00F2,0x00F3,0x00F3,0x00F4,0x00F4,
        0x00F4,0x00F5,0x00F5,0x00F6,0x00F6,0x00F7,0x00F7,0x00F7,
        0x00F8,0x00F8,0x00F9,0x00F9,0x00F9,0x00FA,0x00FA,0x00FA,
        0x00FB,0x00FB,0x00FB,0x00FB,0x00FC,0x00FC,0x00FC,0x00FC,
        0x00FD,0x00FD,0x00FD,0x00FD,0x00FE,0x00FE,0x00FE,0x00FE,
        0x00FE,0x00FE,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,
        0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,
        0x0100,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,
        0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FF,0x00FE,
        0x00FE,0x00FE,0x00FE,0x00FE,0x00FE,0x00FD,0x00FD,0x00FD,
        0x00FD,0x00FC,0x00FC,0x00FC,0x00FC,0x00FB,0x00FB,0x00FB,
        0x00FB,0x00FA,0x00FA,0x00FA,0x00F9,0x00F9,0x00F9,0x00F8,
        0x00F8,0x00F7,0x00F7,0x00F7,0x00F6,0x00F6,0x00F5,0x00F5,
        0x00F4,0x00F4,0x00F4,0x00F3,0x00F3,0x00F2,0x00F2,0x00F1,
        0x00F1,0x00F0,0x00EF,0x00EF,0x00EE,0x00EE,0x00ED,0x00ED,
        0x00EC,0x00EB,0x00EB,0x00EA,0x00EA,0x00E9,0x00E8,0x00E8,
        0x00E7,0x00E6,0x00E6,0x00E5,0x00E4,0x00E3,0x00E3,0x00E2,
        0x00E1,0x00E1,0x00E0,0x00DF,0x00DE,0x00DD,0x00DD,0x00DC,
        0x00DB,0x00DA,0x00D9,0x00D9,0x00D8,0x00D7,0x00D6,0x00D5,
        0x00D4,0x00D3,0x00D3,0x00D2,0x00D1,0x00D0,0x00CF,0x00CE,
        0x00CD,0x00CC,0x00CB,0x00CA,0x00C9,0x00C8,0x00C7,0x00C6,
        0x00C5,0x00C4,0x00C3,0x00C2,0x00C1,0x00C0,0x00BF,0x00BE,
        0x00BD,0x00BC,0x00BB,0x00BA,0x00B9,0x00B8,0x00B7,0x00B6,
        0x00B5,0x00B3,0x00B2,0x00B1,0x00B0,0x00AF,0x00AE,0x00AD,
        0x00AB,0x00AA,0x00A9,0x00A8,0x00A7,0x00A6,0x00A4,0x00A3,
        0x00A2,0x00A1,0x009F,0x009E,0x009D,0x009C,0x009B,0x0099,
        0x0098,0x0097,0x0095,0x0094,0x0093,0x0092,0x0090,0x008F,
        0x008E,0x008C,0x008B,0x008A,0x0088,0x0087,0x0086,0x0084,
        0x0083,0x0082,0x0080,0x007F,0x007E,0x007C,0x007B,0x007A,
        0x0078,0x0077,0x0075,0x0074,0x0073,0x0071,0x0070,0x006E,
        0x006D,0x006C,0x006A,0x0069,0x0067,0x0066,0x0064,0x0063,
        0x0061,0x0060,0x005F,0x005D,0x005C,0x005A,0x0059,0x0057,
        0x0056,0x0054,0x0053,0x0051,0x0050,0x004E,0x004D,0x004B,
        0x004A,0x0048,0x0047,0x0045,0x0044,0x0042,0x0041,0x003F,
        0x003E,0x003C,0x003B,0x0039,0x0038,0x0036,0x0035,0x0033,
        0x0031,0x0030,0x002E,0x002D,0x002B,0x002A,0x0028,0x0027,
        0x0025,0x0024,0x0022,0x0020,0x001F,0x001D,0x001C,0x001A,
        0x0019,0x0017,0x0015,0x0014,0x0012,0x0011,0x000F,0x000E,
        0x000C,0x000A,0x0009,0x0007,0x0006,0x0004,0x0003,0x0001,
        0xFFFF,0xFFFE,0xFFFC,0xFFFB,0xFFF9,0xFFF8,0xFFF6,0xFFF5,
        0xFFF3,0xFFF1,0xFFF0,0xFFEE,0xFFED,0xFFEB,0xFFEA,0xFFE8,
        0xFFE6,0xFFE5,0xFFE3,0xFFE2,0xFFE0,0xFFDF,0xFFDD,0xFFDB,
        0xFFDA,0xFFD8,0xFFD7,0xFFD5,0xFFD4,0xFFD2,0xFFD1,0xFFCF,
        0xFFCE,0xFFCC,0xFFCA,0xFFC9,0xFFC7,0xFFC6,0xFFC4,0xFFC3,
        0xFFC1,0xFFC0,0xFFBE,0xFFBD,0xFFBB,0xFFBA,0xFFB8,0xFFB7,
        0xFFB5,0xFFB4,0xFFB2,0xFFB1,0xFFAF,0xFFAE,0xFFAC,0xFFAB,
        0xFFA9,0xFFA8,0xFFA6,0xFFA5,0xFFA3,0xFFA2,0xFFA0,0xFF9F,
        0xFF9E,0xFF9C,0xFF9B,0xFF99,0xFF98,0xFF96,0xFF95,0xFF93,
        0xFF92,0xFF91,0xFF8F,0xFF8E,0xFF8C,0xFF8B,0xFF8A,0xFF88,
        0xFF87,0xFF85,0xFF84,0xFF83,0xFF81,0xFF80,0xFF7F,0xFF7D,
        0xFF7C,0xFF7B,0xFF79,0xFF78,0xFF77,0xFF75,0xFF74,0xFF73,
        0xFF71,0xFF70,0xFF6F,0xFF6D,0xFF6C,0xFF6B,0xFF6A,0xFF68,
        0xFF67,0xFF66,0xFF64,0xFF63,0xFF62,0xFF61,0xFF60,0xFF5E,
        0xFF5D,0xFF5C,0xFF5B,0xFF59,0xFF58,0xFF57,0xFF56,0xFF55,
        0xFF54,0xFF52,0xFF51,0xFF50,0xFF4F,0xFF4E,0xFF4D,0xFF4C,
        0xFF4A,0xFF49,0xFF48,0xFF47,0xFF46,0xFF45,0xFF44,0xFF43,
        0xFF42,0xFF41,0xFF40,0xFF3F,0xFF3E,0xFF3D,0xFF3C,0xFF3B,
        0xFF3A,0xFF39,0xFF38,0xFF37,0xFF36,0xFF35,0xFF34,0xFF33,
        0xFF32,0xFF31,0xFF30,0xFF2F,0xFF2E,0xFF2D,0xFF2C,0xFF2C,
        0xFF2B,0xFF2A,0xFF29,0xFF28,0xFF27,0xFF26,0xFF26,0xFF25,
        0xFF24,0xFF23,0xFF22,0xFF22,0xFF21,0xFF20,0xFF1F,0xFF1E,
        0xFF1E,0xFF1D,0xFF1C,0xFF1C,0xFF1B,0xFF1A,0xFF19,0xFF19,
        0xFF18,0xFF17,0xFF17,0xFF16,0xFF15,0xFF15,0xFF14,0xFF14,
        0xFF13,0xFF12,0xFF12,0xFF11,0xFF11,0xFF10,0xFF10,0xFF0F,
        0xFF0E,0xFF0E,0xFF0D,0xFF0D,0xFF0C,0xFF0C,0xFF0B,0xFF0B,
        0xFF0B,0xFF0A,0xFF0A,0xFF09,0xFF09,0xFF08,0xFF08,0xFF08,
        0xFF07,0xFF07,0xFF06,0xFF06,0xFF06,0xFF05,0xFF05,0xFF05,
        0xFF04,0xFF04,0xFF04,0xFF04,0xFF03,0xFF03,0xFF03,0xFF03,
        0xFF02,0xFF02,0xFF02,0xFF02,0xFF01,0xFF01,0xFF01,0xFF01,
        0xFF01,0xFF01,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,
        0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,
        0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,
        0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF01,
        0xFF01,0xFF01,0xFF01,0xFF01,0xFF01,0xFF02,0xFF02,0xFF02,
        0xFF02,0xFF03,0xFF03,0xFF03,0xFF03,0xFF04,0xFF04,0xFF04,
        0xFF04,0xFF05,0xFF05,0xFF05,0xFF06,0xFF06,0xFF06,0xFF07,
        0xFF07,0xFF08,0xFF08,0xFF08,0xFF09,0xFF09,0xFF0A,0xFF0A,
        0xFF0B,0xFF0B,0xFF0B,0xFF0C,0xFF0C,0xFF0D,0xFF0D,0xFF0E,
        0xFF0E,0xFF0F,0xFF10,0xFF10,0xFF11,0xFF11,0xFF12,0xFF12,
        0xFF13,0xFF14,0xFF14,0xFF15,0xFF15,0xFF16,0xFF17,0xFF17,
        0xFF18,0xFF19,0xFF19,0xFF1A,0xFF1B,0xFF1C,0xFF1C,0xFF1D,
        0xFF1E,0xFF1E,0xFF1F,0xFF20,0xFF21,0xFF22,0xFF22,0xFF23,
        0xFF24,0xFF25,0xFF26,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,
        0xFF2B,0xFF2C,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,
        0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,
        0xFF3A,0xFF3B,0xFF3C,0xFF3D,0xFF3E,0xFF3F,0xFF40,0xFF41,
        0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,
        0xFF4A,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,
        0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5B,0xFF5C,
        0xFF5D,0xFF5E,0xFF60,0xFF61,0xFF62,0xFF63,0xFF64,0xFF66,
        0xFF67,0xFF68,0xFF6A,0xFF6B,0xFF6C,0xFF6D,0xFF6F,0xFF70,
        0xFF71,0xFF73,0xFF74,0xFF75,0xFF77,0xFF78,0xFF79,0xFF7B,
        0xFF7C,0xFF7D,0xFF7F,0xFF80,0xFF81,0xFF83,0xFF84,0xFF85,
        0xFF87,0xFF88,0xFF8A,0xFF8B,0xFF8C,0xFF8E,0xFF8F,0xFF91,
        0xFF92,0xFF93,0xFF95,0xFF96,0xFF98,0xFF99,0xFF9B,0xFF9C,
        0xFF9E,0xFF9F,0xFFA0,0xFFA2,0xFFA3,0xFFA5,0xFFA6,0xFFA8,
        0xFFA9,0xFFAB,0xFFAC,0xFFAE,0xFFAF,0xFFB1,0xFFB2,0xFFB4,
        0xFFB5,0xFFB7,0xFFB8,0xFFBA,0xFFBB,0xFFBD,0xFFBE,0xFFC0,
        0xFFC1,0xFFC3,0xFFC4,0xFFC6,0xFFC7,0xFFC9,0xFFCA,0xFFCC,
        0xFFCE,0xFFCF,0xFFD1,0xFFD2,0xFFD4,0xFFD5,0xFFD7,0xFFD8,
        0xFFDA,0xFFDB,0xFFDD,0xFFDF,0xFFE0,0xFFE2,0xFFE3,0xFFE5,
        0xFFE6,0xFFE8,0xFFEA,0xFFEB,0xFFED,0xFFEE,0xFFF0,0xFFF1,
        0xFFF3,0xFFF5,0xFFF6,0xFFF8,0xFFF9,0xFFFB,0xFFFC,0xFFFE
};

/*------------------------------------------------------------------------*/


/*
 * IRQ routine...
 */
int bounce=0;
const int bouncetab[]={
125,119,113,107,101, 95, 90, 84, 78, 73, 67, 62, 57, 52, 48, 43,
 39, 35, 32, 28, 25, 22, 20, 17, 15, 13, 12, 11, 10, 10, 10, 10,
 10, 11, 12, 13, 15, 17, 20, 22, 25, 28, 32, 35, 39, 43, 48, 52,
 57, 62, 67, 73, 78, 84, 90, 95,101,107,113,119};

int xball=(XWIN_SIZE>>1)-40,xdir=0,tymer=0;

void update()
{
static i,j,k;

XCopyArea(display,buffer,window,pixcopy,0,0,80,82,xball,bouncetab[bounce++]);
bounce%=60;
XFlush(display);  /* Flush the area copy out... */

if(tymer++==180) xdir=2;

xball+=xdir;
if((xball<-8)||(xball>XWIN_SIZE-70)) xball+=(xdir=-xdir);

XFillRectangle(display, buffer, background, 0, 0, 80, 82);
DrawObject(i=-6,j-=2,k+=1, 1500,40,40);
XFlush(display);  /* Flush the lines and fills to the copy buffer... */
}


/*
 * Calls all of the X nonsense...
 */
main()
{
struct itimerval time;
XEvent evt;
XGCValues val;
unsigned long msk;
unsigned long i,j;

if((display=XOpenDisplay((char *)0))==(Display *)0)
   {
   fprintf(stdout,"Cannot Open Display!\n");
   exit(0);
   }

screen=DefaultScreen(display);

window=XCreateSimpleWindow(display,RootWindow(display,screen),0,
       0,XWIN_SIZE,YWIN_SIZE, 1, BlackPixel(display,screen),
       BlackPixel(display,screen));

colors=XCreateColormap(display,window,DefaultVisual(display,screen),AllocAll);

background=XCreateGC(display, window, 0, (XGCValues *)0);
XSetForeground(display, background, 126);

msk=GCFunction;
val.function=GXclear;
clear=XCreateGC(display, window, msk, &val);

msk=GCFunction;
val.function=GXor;
pixor=XCreateGC(display, window, msk, &val);
XSetForeground(display, pixor, 127);

msk=GCFunction;
val.function=GXor;
pixor2=XCreateGC(display, window, msk, &val);
XSetForeground(display, pixor2, 143);

val.function=GXcopy;
pixcopy=XCreateGC(display, window, msk, &val);
XSetForeground(display, pixcopy, 127);

val.function=GXcopy;
pixcopy2=XCreateGC(display, window, msk, &val);
XSetForeground(display, pixcopy2, 143);

XMapWindow(display, window);

buffer=XCreatePixmap(display,window,80,82,8);

XSelectInput(display, window, StructureNotifyMask);
XNextEvent(display, &evt);
XSelectInput(display, window, NoEventMask);

XFillRectangle(display, window, clear, 0, 0, XWIN_SIZE, YWIN_SIZE);
XFillRectangle(display, window, background, 0, 0, XWIN_SIZE, YWIN_SIZE);

XSetWindowColormap(display,window,colors);

setc(BlackPixel(display,screen),0,0,16384);
setc(WhitePixel(display,screen),0,0,32768);

setc(126,0,0,49152);
setc(127,0,0,0);

for(i=0;i<64;i++)
   {
   j=(i+70)*512;
   if(j>65535) j=65535;
   setc(128+i,j,j,j);
   }

signal(SIGALRM, update);

time.it_interval.tv_sec=0;
time.it_interval.tv_usec=17000;  /* make this match your frame rate */
time.it_value.tv_sec=0;
time.it_value.tv_usec=1;

setitimer(ITIMER_REAL, &(time), (struct itimerval *)0);

while(1) { pause(); }
}


/*
 * Rotate in 3D then convert 3-D to 2-D projection...
 */
void Rotate(short *points3d,short *points2d,short xrot,short yrot,short zrot,
        short distance,short centerx,short centery){
            
short sinx,siny,cosx,cosy,sinz,cosz;
short x,y,z;
long  t,u;

sinx=sincos[xrot&0x3ff];                          /* Get sincos of 3 axes... */
cosx=sincos[(xrot+0x100)&0x3ff];

siny=sincos[yrot&0x3ff];                /* Table is 1024 entries so MOD 1023 */
cosy=sincos[(yrot+0x100)&0x3ff];        /* Cos 0 = Sin PI/4 so 1024/4 = 256! */

sinz=sincos[zrot&0x3ff];
cosz=sincos[(zrot+0x100)&0x3ff];

for(;;) {
        if((x=*(points3d++))==0x7fff) break;    /* See if end of sequence... */
            y=*(points3d++);                    /* otherwise, fetch + go!    */
            z=*(points3d++);

        t =((x*cosz)-(y*sinz))>>8;                    /* Rotate X - Y thru Z */
        u =((y*cosz)+(x*sinz))>>8;

        x =(short)t;
        y =(short)u;

        t =((y*cosx)-(z*sinx))>>8;                    /* Rotate Y - Z thru X */
        u =((z*cosx)+(y*sinx))>>8;
        y =(short)t;
        z =(short)u;

        t =((x*cosy)-(z*siny))>>8;                    /* Rotate X - Z thru Y */
        u =((z*cosy)+(x*siny))>>8;
        x =(short)t;
        z =(short)u;

        *(points2d++)=((long)x<<8)/(z+distance)+centerx;       /* 3-D to 2-D */
        *(points2d++)=((long)y<<8)/(z+distance)+centery;       /* conversion */
        }
*(points2d++)=0x7fff;                /* Mark the end of table with MAXINT... */
}


/*
 * Draw an object with hidden faces...
 */
void DrawObject(short xrot,short yrot,
                short zrot,short distance,short centerx,short centery){

short xypoints[512];       /* Buffer for pts converted to 2-D... 512's enuff */
XPoint pts[32];            /* No face with 33 points on it.  =)  */

/*
 * Face data:
 * NumPoints, color, point1, point2, point3,...
 * Terminate list with zero for numpoints
 */

static short connect[]={
        0x06,0x00,0x00,0x01,0x02,0x03,0x04,0x00,       /* Black patches */
        0x06,0x00,0x05,0x06,0x07,0x08,0x09,0x05,
        0x06,0x00,0x0A,0x0B,0x0C,0x0D,0x0E,0x0A,
        0x06,0x00,0x0F,0x10,0x11,0x12,0x13,0x0F,
        0x06,0x00,0x14,0x15,0x16,0x17,0x18,0x14,
        0x06,0x00,0x19,0x1A,0x1B,0x1C,0x1D,0x19,
        0x06,0x00,0x1E,0x1F,0x20,0x21,0x22,0x1E,
        0x06,0x00,0x23,0x24,0x25,0x26,0x27,0x23,
        0x06,0x00,0x28,0x29,0x2A,0x2B,0x2C,0x28,
        0x06,0x00,0x2D,0x2E,0x2F,0x30,0x31,0x2D,
        0x06,0x00,0x32,0x33,0x34,0x35,0x36,0x32,
        0x06,0x00,0x37,0x38,0x39,0x3A,0x3B,0x37,

        0x07,0x01,0x03,0x02,0x33,0x32,0x14,0x18,0x03,  /* White Patches */
        0x07,0x01,0x08,0x07,0x15,0x14,0x32,0x36,0x08,
        0x07,0x01,0x0D,0x0C,0x29,0x28,0x1E,0x22,0x0D,
        0x07,0x01,0x12,0x11,0x1F,0x1E,0x28,0x2C,0x12,
        0x07,0x01,0x26,0x25,0x10,0x0F,0x00,0x04,0x26,
        0x07,0x01,0x30,0x2F,0x01,0x00,0x0F,0x13,0x30,
        0x07,0x01,0x3A,0x39,0x0B,0x0A,0x05,0x09,0x3A,
        0x07,0x01,0x1C,0x1B,0x06,0x05,0x0A,0x0E,0x1C,
        0x07,0x01,0x17,0x16,0x1A,0x19,0x23,0x27,0x17,
        0x07,0x01,0x21,0x20,0x24,0x23,0x19,0x1D,0x21,
        0x07,0x01,0x2B,0x2A,0x38,0x37,0x2D,0x31,0x2B,
        0x07,0x01,0x35,0x34,0x2E,0x2D,0x37,0x3B,0x35,
        0x07,0x01,0x04,0x03,0x18,0x17,0x27,0x26,0x04,
        0x07,0x01,0x15,0x07,0x06,0x1B,0x1A,0x16,0x15,
        0x07,0x01,0x22,0x21,0x1D,0x1C,0x0E,0x0D,0x22,
        0x07,0x01,0x11,0x10,0x25,0x24,0x20,0x1F,0x11,
        0x07,0x01,0x0C,0x0B,0x39,0x38,0x2A,0x29,0x0C,
        0x07,0x01,0x13,0x12,0x2C,0x2B,0x31,0x30,0x13,
        0x07,0x01,0x02,0x01,0x2F,0x2E,0x34,0x33,0x02,
        0x07,0x01,0x09,0x08,0x36,0x35,0x3B,0x3A,0x09,
        0x00
};


/*
 * Obj Coords in x,y,z format...delineate end of list with short MAXINT
 * This list is optimized down to 5*12 = 60 points.
 */

static short coords[]={
      40,   0,-195,
      80, -65,-170,
     146, -40,-130,
     146,  40,-130,
      80,  65,-170,
      40,   0, 195,
      80,  65, 170,
     146,  40, 130,
     146, -40, 130,
      80, -65, 170,
     -40,   0, 195,
     -80, -65, 170,
    -146, -40, 130,
    -146,  40, 130,
     -80,  65, 170,
     -40,   0,-195,
     -80,  65,-170,
    -146,  40,-130,
    -146, -40,-130,
     -80, -65,-170,
     195,  40,   0,
     170,  80,  65,
     130, 146,  40,
     130, 146, -40,
     170,  80, -65,
       0, 195,  40,
      65, 170,  80,
      40, 130, 146,
     -40, 130, 146,
     -65, 170,  80,
    -195,  40,   0,
    -170,  80, -65,
    -130, 146, -40,
    -130, 146,  40,
    -170,  80,  65,
       0, 195, -40,
     -65, 170, -80,
     -40, 130,-146,
      40, 130,-146,
      65, 170, -80,
    -195, -40,   0,
    -170, -80,  65,
    -130,-146,  40,
    -130,-146, -40,
    -170, -80, -65,
       0,-195, -40,
      65,-170, -80,
      40,-130,-146,
     -40,-130,-146,
     -65,-170, -80,
     195, -40,   0,
     170, -80, -65,
     130,-146, -40,
     130,-146,  40,
     170, -80,  65,
       0,-195,  40,
     -65,-170,  80,
     -40,-130, 146,
      40,-130, 146,
      65,-170,  80,
     32767 };


/*
 * Object definition for DrawObject()...
 */
static struct Object myobject;

short i,j,k,x1,y1,x2,y2,x3,y3,x4,y4,*cptr, faccolor, clock;

myobject.Faces=connect;
myobject.Points=coords;

Rotate(myobject.Points,xypoints,xrot,yrot,zrot,distance,centerx,centery);
cptr=myobject.Faces;

for(;;){ 
        if(!(j=*(cptr++)))break;                  /* Check if end of list... */
	
        faccolor=*(cptr++);

        x1=xypoints[(*cptr)<<1];        y1=xypoints[((*(cptr++))<<1)+1];
        x2=xypoints[(*cptr)<<1];        y2=xypoints[((*(cptr++))<<1)+1];
        x3=xypoints[(*cptr)<<1];        y3=xypoints[((*(cptr++))<<1)+1];

        clock=((y3-y1)*(x2-x1)-(x3-x1)*(y2-y1));
        if(clock>0)        /* See if face viz... */
                {                                  
                pts[0].x=x1;   pts[0].y=y1;
                pts[1].x=x2;   pts[1].y=y2;
                pts[2].x=x3;   pts[2].y=y3;

                for(i=0+3;i<(j-3)+3;i++)
		   {
                   pts[i].x=xypoints[(*cptr)<<1];
                   pts[i].y=xypoints[((*(cptr++))<<1)+1];
                   }
                
                 if(!faccolor)  /* black patch */
                 XFillPolygon(display,buffer,pixcopy,(XPoint *)&pts,j,
                              Convex,CoordModeOrigin);
	         else
		 {              /* white lightsourced patch */
		 clock=(clock>>1)+128;
                 if (clock>191) clock=191;
                 XSetForeground(display,pixcopy2,clock);
                 XFillPolygon(display,buffer,pixcopy2,(XPoint *)&pts,j,
                              Convex,CoordModeOrigin);
                 XDrawLines(display,buffer,pixcopy,(XPoint *)&pts,j,
                              CoordModeOrigin);
	         }
                } else cptr+=(j-3);  /* face is hidden */
        }
}
