// 1k Metaballs by KilledWhale
// Some extra bytes can be stripped by removing non needed SDL_Init, SDL_Quit and SDL_ShowCursor.
// 10.08.2010
// ---------------------------
// Compiling:
// ---------------------------
// gcc -c -Os `sdl-config --cflags` -o metab.o metab.c
// bold -c -a `sdl-config --libs` -lGL -o metab metab.o
// gzip metab
// advdef -z -4 metab.gz
// echo 'a=/tmp/I;tail -n+2 $0|zcat>$a;chmod +x $a;$a;rm $a;exit' > metab
// cat metab.gz >> metab
// rm metab.gz
// chmod a+x metab
 
#include "GL/gl.h"
#include "SDL.h"
 
const GLchar *vsh = "\
varying vec4 p;\
void main(){\
p=gl_Vertex;\
gl_Position=ftransform();\
}";
 
const GLchar *fsh = "\
varying vec4 p;\
uniform vec4 b[5];\
vec4 f;\
void main(){\
for(int i=0;i<5;i++){\
f.x+=b[i].z/(length(p.xy-b[i].xy)*11);\
}\
gl_FragColor=vec4(f.x,f.x,f.x,1);\
}";
 
float ballp[20];
 
static int balloc;
static SDL_Event e;
static float secs;
 
int main() {
	SDL_Init(SDL_INIT_VIDEO);
	SDL_SetVideoMode(1024, 768, 0, SDL_OPENGL);
	SDL_ShowCursor(SDL_DISABLE);
 
	GLuint v,p;
	p = glCreateProgram();
 
	v = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(v, 1, &vsh, 0);
	glCompileShader(v);
	glAttachShader(p, v);
 
	v = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(v, 1, &fsh, 0);	
	glCompileShader(v);
	glAttachShader(p, v);
 
	glLinkProgram(p);
	glUseProgram(p);
 
	balloc = glGetUniformLocation(p, "b");
	a:
	  	secs = SDL_GetTicks() / 200.0;
		for (p = 0; p < 20; p += 4) {
		  	srand(p);
			ballp[p+2] = (rand() % 200 + 100) / 200.0;
			ballp[p+1] = cos(((rand() % 200 - 100) / 200.0) * secs);
		  	ballp[p] = cos(((rand() % 200 - 100) / 200.0) * secs);
		}
		glUniform4fv(balloc, 5, ballp);
		glRecti(-1, -1, 1, 1);
		SDL_GL_SwapBuffers();
 
		SDL_PollEvent(&e);
		if (e.type == SDL_QUIT || e.type == SDL_KEYDOWN)
			goto b;
	goto a;
	b:
	SDL_Quit();
	return 0;
}