#define float double
/*** 3D Rotating dodekahedron ***/
/*** By Kim 0yhus 1992 (L)    ***/
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>


Display *display;
Window window;
GC gc;
Colormap colors, colors2;

Visual       *visual;
XColor        xcolor;
XSizeHints    hints;
 

void
  OpenX()
{
  int n,x,y;

  display = XOpenDisplay(0);
  x=DisplayWidth( display,0);
  y=DisplayHeight(display,0);
  window=
    XCreateSimpleWindow(display,RootWindow(display,0),1,1,x,y,0,1,0);
  hints.flags=PPosition | USPosition;
  hints.x=100;
  hints.y=100;
  XSetStandardProperties(display, window, "kim's urkehulmate",
			 NULL,NULL,NULL,0, &hints);
  XMapWindow(display,window);
  XSync(display,True);
  sleep(1);
  
  visual=DefaultVisual(display, 0);
  colors =XCreateColormap(display,window,visual,AllocAll);
  colors2=XCreateColormap(display,window,visual,AllocAll);

  xcolor.flags= DoRed | DoGreen | DoBlue;
  for(n=0; n<16; n++) 
    {
      xcolor.pixel= n;
      if((n&3)==0)
	{
	  xcolor.red  =100<<8;
	  xcolor.green= 85<<8;
	  xcolor.blue =  0<<8;
	}
      if((n&3)==1)
	{
	  xcolor.red  =100<<8;
	  xcolor.green=255<<8;
	  xcolor.blue =  0<<8;
	}
      if((n&3)==2)
	{
	  xcolor.red  =255<<8;
	  xcolor.green=  0<<8;
	  xcolor.blue =  0<<8;
	}
      if((n&3)==3)
	{
	  xcolor.red  =247<<8;
	  xcolor.green=251<<8;
	  xcolor.blue =  0<<8;
	}
      XStoreColor(display, colors, &xcolor);
    }
  XInstallColormap(display,colors);
  for(n=0; n<16; n++) 
    {
      xcolor.pixel= n;
      if((n>>2)==0)
	{
	  xcolor.red  =100<<8;
	  xcolor.green= 85<<8;
	  xcolor.blue =  0<<8;
	}
      if((n>>2)==1)
	{
	  xcolor.red  =100<<8;
	  xcolor.green=255<<8;
	  xcolor.blue =  0<<8;
	}
      if((n>>2)==2)
	{
	  xcolor.red  =255<<8;
	  xcolor.green=  0<<8;
	  xcolor.blue =  0<<8;
	}
      if((n>>2)==3)
	{
	  xcolor.red  =247<<8;
	  xcolor.green=251<<8;
	  xcolor.blue =  0<<8;
	}
      XStoreColor(display, colors2, &xcolor);
    }
  XInstallColormap(display,colors2);
  XSetWindowColormap(display,window,colors);
  gc=XCreateGC(display,window,0,0);
  XSync(display,True);

  for(n=0; n<256; n++)
    {
      XSetForeground(display,gc,n);
      XFillRectangle(display,window,gc,n*4,0,4,256*2);
      XSync(display,True);
    }
}

void
  CloseX()
{
  XUninstallColormap(display,colors);
  XUninstallColormap(display,colors2);
  XCloseDisplay(display);
}


#define PERSPEK 2000
/* Antall punkter fra skjerm til bruker. */
/*              0   1    2    3   4   5    6    7   8   9   10   11 */
  int figX[]={ 62,-62,  62, -62,  0,  0,   0,   0,160,160,-160,-160,100,100,100,
100,-100,-100,-100,-100};
  int figY[]={160,160,-160,-160, 62,-62,  62, -62,  0,  0,   0,   0,100,100,-100
,-100,100,100,-100,-100};
  int figZ[]={  0,  0,   0,   0,160,160,-160,-160, 62,-62,  62, -62,100,-100,100
,-100,100,-100,100,-100};
int figFra[]={0, 0, 0, 1, 1,2, 2, 2, 3, 3,4, 4, 4, 5, 5,6, 6, 6, 7, 7,8, 8, 8, 9
, 9,10,10,10,11,11};
int figTil[]={1,12,13,16,17,3,14,15,18,19,5,12,16,14,18,7,13,17,15,19,9,12,14,13
,15,11,16,18,17,19};
int figPunkt=20;
int figLine =30;
int Xleft[30], Yleft[30], Xright[30], Yright[30];

XSegment q9[100],q10[100],q11[100],q12[100], *tX;
XSegment *OldLinesL= &q9[0], *OldLinesR=&q10[0],
         *LinesL   =&q11[0], *LinesR   =&q12[0];

main()
{
  int a, n, k, i;
  double v;
  short int S,C,S2,C2,S3,C3,SS,CC;
  short int x1,y1,z1,x2,y2,z2;
  unsigned long plane_mask=3;
  int OrigoX, OrigoY;
  
  OpenX();
  OrigoX=DisplayWidth( display,0)/2;
  OrigoY=DisplayHeight(display,0)/2;

  XSetForeground(display,gc,0);
  XFillRectangle(display,window,gc,0,0,OrigoX*2,OrigoY*2);
  XSync(display,True);

  SS=sin(.1) *(1<<14);
  CC=cos(.1) *(1<<14);

  for(v=0; v<=20*3.14159265358979323846264338327950288419716939937510; v+=0.04)
    {
      S=sin(v)         *(1<<14);
      C=cos(v)         *(1<<14);
      S2=sin(v/13.782) *(1<<14);
      C2=cos(v/13.782) *(1<<14);
      S3=sin(v*0.13782)*(1<<14);
      C3=cos(v*0.13782)*(1<<14);
      for(n=0; n<figPunkt; n++) 
	{
	  x1=figX[n]<<1;
	  y1=figY[n]<<1;
	  z1=figZ[n]<<1;

	  x2=(C*x1-S*z1+(1<<13))>>14;
	  y2=y1;
	  z2=(C*z1+S*x1+(1<<13))>>14;

	  x1=(C2*y2+S2*x2+(1<<13))>>14;
	  y1=(C2*x2-S2*y2+(1<<13))>>14;
	  z1=z2;

	  x2=x1;
	  y2=(C3*y1-S3*z1+(1<<13))>>14;
	  z2=(C3*z1+S3*y1+(1<<13))>>14;
	  
	  Xleft[n]=PERSPEK*x2/(z2+PERSPEK)+OrigoX;
	  Yleft[n]=PERSPEK*y2/(z2+PERSPEK)+OrigoY;

	  x1=(CC*x2-SS*z2+(1<<13))>>14;
	  y1=y2;
	  z1=(CC*z2+SS*x2+(1<<13))>>14;

	  Xright[n]=PERSPEK*x1/(z1+PERSPEK)+OrigoX;
	  Yright[n]=PERSPEK*y1/(z1+PERSPEK)+OrigoY;
	}

      XSetPlaneMask(display,gc,plane_mask&(1+4));
      for(n=0; n<figLine; n++) 
	{
	  LinesL[n].x1=Xleft[figFra[n]];
	  LinesL[n].y1=Yleft[figFra[n]];
	  LinesL[n].x2=Xleft[figTil[n]];
	  LinesL[n].y2=Yleft[figTil[n]];
	}
      XSetForeground(display,gc,1+4);
      XDrawSegments(display,window,gc,LinesL,figLine);

      XSetPlaneMask(display,gc,plane_mask&(2+8));
      for(n=0; n<figLine; n++) 
	{
	  LinesR[n].x1=Xright[figFra[n]];
	  LinesR[n].y1=Yright[figFra[n]];
	  LinesR[n].x2=Xright[figTil[n]];
	  LinesR[n].y2=Yright[figTil[n]];
	}
      XSetForeground(display,gc,2+8);
      XDrawSegments(display,window,gc,LinesR,figLine);

      XSync(display,True);
      XSync(display,True);
      if(plane_mask!=3)
	XSetWindowColormap(display,window,colors2);
      else
	XSetWindowColormap(display,window,colors);
      XSync(display,True);
      XSync(display,True);

      plane_mask^=15;
      if(v!=0)
	{
	  XSetPlaneMask(display,gc,plane_mask&(1+4));
	  XSetForeground(display,gc,0);
	  XDrawSegments(display,window,gc,OldLinesL,figLine);
	  
	  XSetPlaneMask(display,gc,plane_mask&(2+8));
	  XSetForeground(display,gc,0);
	  XDrawSegments(display,window,gc,OldLinesR,figLine);
	}
      tX=OldLinesL;
      OldLinesL=LinesL;
      LinesL=tX;
      tX=OldLinesR;
      OldLinesR=LinesR;
      LinesR=tX;
    }
  sleep(2);
  CloseX();
}













