// Bez prekalkulacji. Mam szybkiego kompa w miare ;>
// gcc -O3 -lm -lvga -lvgagl test.c

// Zredukuj jasnosc monitora tak, by czern byla naprawde
// ciemna. Zgas swiatlo, dobierz kontrast i uruchom to...

#include <vga.h>
#include <math.h>
#include <vgagl.h>
#include <stdlib.h>

#define ILE_KOLEK 500

#define rnd(x)   (x*(float)rand()/(RAND_MAX+1.0))
#define min(a,b) (a>b?b:a)

struct kolko {
  float phase,inc,p2,i2,p3,i3;
  int x,y,rad2,able;
};

struct kolko k[ILE_KOLEK];

main() {
  GraphicsContext physicalscreen;
  int i=0,w,v,tim=0.3,bx;
  float m,q;
  srand(time(0));
  for (;i<ILE_KOLEK;i++) {
    k[i].phase=rnd(10);
    k[i].inc=rnd(0.03)+0.005;
    k[i].p2=rnd(10);
    k[i].i2=rnd(0.03)+0.005;
    k[i].p3=rnd(10);
    k[i].i3=rnd(0.03)+0.005;
    k[i].x=(int)rnd(315);
    k[i].y=(int)rnd(195);
    m=min(k[i].x,k[i].y);
    m=min(m,320-k[i].x);
    m=min(m,200-k[i].y);
    m=min(m,50);
    k[i].rad2=(rnd(m)+3)/2;
    m=min(k[i].x-(int)(2*k[i].rad2),k[i].y-(int)(2*k[i].rad2));
    m=min(m,320-k[i].x-(int)(2*k[i].rad2));
    m=min(m,200-k[i].y-(int)(2*k[i].rad2));
    k[i].able=(int)m;
  }
  vga_setmode(G320x200x256);
  gl_setcontextvga(G320x200x256);
  gl_getcontext(&physicalscreen);
  gl_setcontextvgavirtual(G320x200x256);
  gl_copyscreen(&physicalscreen);
  while (++tim) {
    if (!(tim%4)) {
      float a=(sin(tim/120.0)+1)/10, b=(sin(tim/100.0)+1)/10, c=(sin(tim/140.0)+1)/10;
      for (bx=0;bx<255;bx++) vga_setpalette(bx,(int)(bx*c),(int)(bx*a),(int)(bx*b));
    }
    for (i=0;i<ILE_KOLEK;i++)  {
      q=1+sin(k[i].phase+=k[i].inc);
      w=(int)(sin(k[i].p2+=k[i].i2)*k[i].able)+k[i].x;
      v=(int)(sin(k[i].p3+=k[i].i3)*k[i].able)+k[i].y;
      gl_circle(w,v,k[i].rad2*q,(int)(120.0*(2-q)));
    }
    gl_copyscreen(&physicalscreen);
    gl_clearscreen(0);
  }  
}
		
			    
