/* circle.c - draws a circle or oval with an iterative algorithm
 * Chris Lu <lulabs.net>
 * compile with gcc -o circle -lSDL circle.c
 */

#include <SDL/SDL.h>
#include <stdio.h>

#define XRES 640
#define YRES 480
/* this is magenta; change as desired */
#define MAX_COLOR 0x00FF00FF
#define COLOR_INCREMENT 0x00220022

SDL_Surface *screen;
double x, y, eps;

void update()
{
	unsigned int cur, *p;
	int ry, rx, pos;

	ry = (int)y + YRES/2;
	rx = (int)x + XRES/2;
	pos = ry * XRES + rx;

	SDL_LockSurface(screen);
	p = screen->pixels;

	if(pos >= 0 && pos < XRES*YRES) {
		cur = p[pos];
		p[pos] = (cur >= MAX_COLOR) ? MAX_COLOR : cur + COLOR_INCREMENT;
	}

	SDL_UnlockSurface(screen);
	SDL_Flip(screen);

	/* the magic is here */
	x -= eps*y;
	y += eps*x;
}

int main(int argc, char **argv)
{
	int i;
	int delay;
	struct timeval nao;
	unsigned int before;

	if(argc != 4) {
		printf("Usage: %s <initial x> <initial y> <epsilon>\n"
		       "Try %s 100 0 0.1\n", argv[0], argv[0]);
		return 1;
	}

	x = atof(argv[1]);
	y = atof(argv[2]);
	eps = atof(argv[3]);

	screen = NULL;
	if(SDL_Init(SDL_INIT_VIDEO) < 0) {
		printf("Video init failed: %s\n", SDL_GetError());
		return 1;
	}
	atexit(SDL_Quit);
	screen = SDL_SetVideoMode(XRES, YRES, 32, SDL_SWSURFACE);
	if(!screen) {
		printf("Video mode init failed: %s\n", SDL_GetError());
		return 1;
	}

	gettimeofday(&nao, NULL);
	before = nao.tv_usec;
	while (1) {
		update();
		gettimeofday(&nao, NULL);
		delay = 5000 - (1000000 + nao.tv_usec - before)%1000000;
		if(delay>0)
			usleep(delay);
		gettimeofday(&nao, NULL);
		before = nao.tv_usec;
	}
	return 1;
}

