int main(int argc, char *argv[])
{
	SDL_Surface *screen, *screen2;
	SDL_Event event;
	SDL_Joystick *joystick;
	rotentry *rot;
	uint32_t i=0, prev_tick=SDL_GetTicks(), tick, is;
	uint16_t rot_a, rot_s, *stats, *stats2, rot_r, frame_ms;
	int8_t exit_key=0, rotate_left=0, rotate_right=0, thrust=0, time_down=0, time_up=0, crash=0;
	uint8_t *screen32, ib, il;
	float time_scale, time_factor, space_scale;
	double cam_x, cam_y;
	/*FONT*/
	SDL_Surface *font_surf;
	uint8_t *font;
	/*END FONT*/
	char *line1;
	/*ROCKET*/
	SDL_Surface *rocket_surf, *rocket_alpha;
	uint16_t rocket_d;
	uint8_t *rocketRGB, *rocket_scaled, *rocket_rot, rocket_power;
	vector rocket;
	float dbb, dbb2, dbc;
	/*END ROCKET*/
	/*STAR*/
	star_t star[STAR_COUNT];
	uint32_t cam_star_x, cam_star_y;
	/*END STAR*/
	body_t body[BODY_COUNT];
	SDL_Init(SDL_INIT_EVERYTHING);
	atexit(SDL_Quit);
	joystick = SDL_JoystickOpen(0);
	screen=SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE);
	screen2 = IMG_Load("screen.png");
	screen32 = calloc (320 * 240 * 4, sizeof(uint8_t));
	SDL_ShowCursor(SDL_DISABLE);
	rot=rot_lut_load(&rot_a, &rot_r, &rot_s);	//load the rotation LUT
	font_surf=IMG_Load("TinyFont.bmp");
	font = surf2font(font_surf, 6, 8);
	SDL_FreeSurface(font_surf);
	line1 = calloc (54, sizeof(char));
	body[0].surf=IMG_Load("earth131a.png");		//load sprite
	body[1].surf=IMG_Load("moon37a.png");		//load sprite
	body[0].letter_surf=IMG_Load("blueEa.png");	//load Earth's letter
	body[1].letter_surf=IMG_Load("greyMa.png");	//load Moon's letter
	for (ib=0; ib<BODY_COUNT; ib++)
	{
		SDL_LockSurface(body[ib].surf);
		body[ib].RGB=RGBarray(body[ib].surf, &body[ib].diam, &body[ib].diam, &body[ib].power);	//turn it into an array
		SDL_FreeSurface(body[ib].surf);
		body[ib].rot = calloc (body[ib].diam * body[ib].diam * 4, sizeof(uint8_t));	//turn it into an array
		body[ib].scaled = scale2(body[ib].RGB, &body[ib].diam, &body[ib].diam, &body[ib].power);
		free(body[ib].RGB);
		body[ib].letter=RGBarray_np(body[ib].letter_surf, &body[ib].letter_w, &body[ib].letter_h);
		free(body[ib].letter_surf);
	}
	rocket_surf=IMG_Load("rocket1.png");		//load sprite
	SDL_LockSurface(rocket_surf);
	rocketRGB=RGBarray(rocket_surf, &rocket_d, &rocket_d, &rocket_power);	//turn it into an array
	SDL_FreeSurface(rocket_surf);
	rocket_alpha=IMG_Load("rocket1alpha.png");		//load alpha layer
	SDL_LockSurface(rocket_alpha);
	add_alpha(rocket_alpha, rocketRGB, rocket_d, rocket_power);	//integrate the alpha layer
	SDL_FreeSurface(rocket_alpha);
	rocket_rot = calloc (rocket_d * rocket_d * 4, sizeof(uint8_t));	//turn it into an array
	rocket_scaled = scale2(rocketRGB, &rocket_d, &rocket_d, &rocket_power);
	free(rocketRGB);
	for (is=0; is<STAR_COUNT; is++)
	{
		star[is].x = rand_u32()%STAR_FIELD_SIZE;
		star[is].y = rand_u32()%STAR_FIELD_SIZE;
//		star[is].mag = (rand_u32()%256)*(rand_u32()%256)*(rand_u32()%256)>>16;
		star[is].mag = (rand_u32()%256)*(rand_u32()%256)>>8;
	}
	frame_ms = 20;	//last frame duration in real world milliseconds
	time_scale = 1;	//unit = game seconds / real world seconds
	time_factor = frame_ms * 0.001 * time_scale; //unit = seconds / frame
	space_scale = 0.00001;	//unit = 1 / (meter/pixel)
	rocket.mass = 3038500;	//3038500 kg
	rocket.thrust = 34020000;	//34.02 Mega Newtons
	rocket.pos_x = 0;	//meters
	rocket.pos_y = -6678000;	//meters
	rocket.speed_x = -7730;	//meters / second
	rocket.speed_y = 0;
	rocket.thrust_x = 0;
	rocket.thrust_y = 0;
	rocket.angle = 0;
	body[0].pos_x = 0;
	body[0].pos_y = 0;
	body[0].speed_x = 12.13;
	body[0].speed_y = 0;
	body[0].mass = 3.98730056e14;	//5.9742e24 * G (G = 6.6742e-11)
	body[0].radius2 = 40680631590769.0;	//6378137^2
	body[0].angle = 0;
	body[0].rot_spd = 0.000011605762776514406680156354228817;	//1 / 86,164.091 seconds
	body[0].link_count = 1;
	body[0].linked_body_ID = calloc (body[0].link_count, sizeof(uint8_t));
	body[0].linked_body_ID[0] = 1;	//Earth is linked to Moon (ID 1)
	body[1].pos_x = 0;
	body[1].pos_y = -405696000;	//meters (apogee)
	body[1].speed_x = -986;	//meters / second
	body[1].speed_y = 0;
	body[1].mass = 4.90400193e12;	//7.3477e22 * G (G = 6.6742e-11)
	body[1].radius2 = 3021130659600.0;	//1738140^2
	body[1].angle = 0;
	body[1].rot_spd = 4.23623862e-7;	//1 / 2,360,584.68 seconds
	body[1].link_count = 1;
	body[1].linked_body_ID = calloc (body[1].link_count, sizeof(uint8_t));
	body[1].linked_body_ID[0] = 0;	//Moon is linked to Earth (ID 0)
	for (ib=0; ib<BODY_COUNT; ib++)
		rotation(body[ib].scaled, body[ib].rot, body[ib].diam, rot, rot_s, body[ib].ia, rot_a, rot_r, body[ib].power);
	rotation(rocket_scaled, rocket_rot, rocket_d, rot, rot_s, rocket.ia, rot_a, rot_r, rocket_power);
	while (exit_key==0)
	{
		if (SDL_PollEvent(&event))
		{
			if (event.type==SDL_KEYDOWN)
				switch (event.key.keysym.sym)
				{
					case SDLK_q:
						exit_key=1;
						break;
					case SDLK_UP:
						thrust=1;
						break;
					case SDLK_LEFT:
						rotate_left=1;
						break;
					case SDLK_RIGHT:
						rotate_right=1;
						break;
					case SDLK_KP7:
						time_down=1;
						break;
					case SDLK_KP9:
						time_up=1;
						break;
				}
			if (event.type==SDL_KEYUP)
				switch (event.key.keysym.sym)
				{
					case SDLK_UP:
						thrust=0;
						break;
					case SDLK_LEFT:
						rotate_left=0;
						break;
					case SDLK_RIGHT:
						rotate_right=0;
						break;
				}
			if (event.type==SDL_JOYBUTTONDOWN)
				switch (event.jbutton.button)
				{
					case GPB_START:
						exit_key=1;
						break;
					case GPB_UP:
						thrust=1;
						break;
					case GPB_LEFT:
						rotate_left=1;
						break;
					case GPB_RIGHT:
						rotate_right=1;
						break;
					case GPB_L:
						time_down=1;
						break;
					case GPB_R:
						time_up=1;
						break;
				}
			if (event.type==SDL_JOYBUTTONUP)
				switch (event.jbutton.button)
				{
					case GPB_UP:
						thrust=0;
						break;
					case GPB_LEFT:
						rotate_left=0;
						break;
					case GPB_RIGHT:
						rotate_right=0;
						break;
				}
		}
		/********************Physics********************/
		tick = SDL_GetTicks();
		frame_ms = tick - prev_tick;
		prev_tick = tick;
sprintf(line1, "%d ms", frame_ms);
		if (frame_ms>40)	//frame duration capping
			frame_ms = 40;
		if (time_down==1)
		{
			time_scale*=0.5;
			time_down=0;
		}
		if (time_up==1)
		{
			time_scale*=2;
			time_up=0;
		}
		time_factor = frame_ms * 0.001 * time_scale;
		if (rotate_left==1)
			rocket.angle-=0.01;
		if (rotate_right==1)
			rocket.angle+=0.01;
		if (thrust==1)
		{
			rocket.thrust_y = rocket.thrust * cosf(rocket.angle * pi * 2);
			rocket.thrust_x = rocket.thrust * -sinf(rocket.angle * pi * 2);
		}
		else
		{
			rocket.thrust_y = 0;
			rocket.thrust_x = 0;
		}
		rocket.angle = fmodf(rocket.angle, 1);
		rocket.prev_ia = rocket.ia;
		rocket.ia = nearbyint(rocket.angle * ((rot_a-1)<<2));
		rocket.ia%=(rot_a-1)<<2;
		/*N-body interactions start here*/
		rocket.vect_y = 0;
		rocket.vect_x = 0;
		for (ib=0; ib<BODY_COUNT; ib++)		//angles
		{
			body[ib].angle -= body[ib].rot_spd * time_factor;
			body[ib].angle = fmodf(body[ib].angle, 1);
			body[ib].prev_ia = body[ib].ia;
			body[ib].ia = nearbyint(body[ib].angle * ((rot_a-1)<<2));
			body[ib].ia%=(rot_a-1)<<2;
			/*Inter-body interactions*/
			body[ib].vect_y = 0;
			body[ib].vect_x = 0;
			for (il=0; il<body[ib].link_count; il++)
			{
				dbb2 = distance2(body[ib].pos_x, body[ib].pos_y, body[body[ib].linked_body_ID[il]].pos_x, body[body[ib].linked_body_ID[il]].pos_y);	//distance body-body
				dbb = sqrt(dbb2);
				body[ib].vect_mag = time_factor * body[body[ib].linked_body_ID[il]].mass / dbb2;
				body[ib].vect_y += (body[ib].vect_mag * (body[ib].pos_y - body[body[ib].linked_body_ID[il]].pos_y)) / dbb;
				body[ib].vect_x += (body[ib].vect_mag * (body[ib].pos_x - body[body[ib].linked_body_ID[il]].pos_x)) / dbb;
			}
			body[ib].speed_y-=body[ib].vect_y;	//meters / second
			body[ib].speed_x-=body[ib].vect_x;	//meters / second
			body[ib].pos_y+=time_factor*body[ib].speed_y;	//meters
			body[ib].pos_x+=time_factor*body[ib].speed_x;	//meters
			/*Rocket-bodies interactions*/
			dbb2 = distance2(body[ib].pos_x, body[ib].pos_y, rocket.pos_x, rocket.pos_y);	//distance earth-rocket in meters
			if (dbb2<body[ib].radius2)
				crash=1;
			dbb = sqrt(dbb2);
			rocket.vect_mag = time_factor * body[ib].mass / dbb2;
			rocket.vect_y += (rocket.vect_mag * (rocket.pos_y-body[ib].pos_y)) / dbb;
			rocket.vect_x += (rocket.vect_mag * (rocket.pos_x-body[ib].pos_x)) / dbb;
		}
		if (crash==0)
		{
			rocket.speed_y-=rocket.thrust_y/rocket.mass + rocket.vect_y;	//meters / second
			rocket.speed_x-=rocket.thrust_x/rocket.mass + rocket.vect_x;	//meters / second
			rocket.pos_y+=time_factor*rocket.speed_y;	//meters
			rocket.pos_x+=time_factor*rocket.speed_x;	//meters
		}
		/********************Graphics********************/
		cam_x=rocket.pos_x;
		cam_y=rocket.pos_y;
		for (ib=0; ib<BODY_COUNT; ib++)
		{
			if (body[ib].ia!=body[ib].prev_ia)
				rotation(body[ib].scaled, body[ib].rot, body[ib].diam, rot, rot_s, body[ib].ia, rot_a, rot_r, body[ib].power);
			blit_center((uint32_t *)screen32, (uint32_t *)body[ib].rot, body[ib].diam>>rot_s, body[ib].diam>>rot_s, nearbyint((body[ib].pos_x-cam_x)*space_scale+160), nearbyint((body[ib].pos_y-cam_y)*space_scale+120), 0);
			dbc = sqrt(distance2(body[ib].pos_x, body[ib].pos_y, cam_x, cam_y)*space_scale*space_scale);
			if (dbc>200 && tick%(int)(dbc+200)>200)
				blit_center((uint32_t *)screen32, (uint32_t *)body[ib].letter, body[ib].letter_w, body[ib].letter_h, nearbyint(((body[ib].pos_x-cam_x)*space_scale)/dbc*160+160), nearbyint(((body[ib].pos_y-cam_y)*space_scale)/dbc*120+120), 0);
		}
		if (rocket.ia!=rocket.prev_ia)
			rotation(rocket_scaled, rocket_rot, rocket_d, rot, rot_s, rocket.ia, rot_a, rot_r, rocket_power);
		blit_center((uint32_t *)screen32, (uint32_t *)rocket_rot, rocket_d>>rot_s, rocket_d>>rot_s, nearbyint((rocket.pos_x-cam_x)*space_scale+160), nearbyint((rocket.pos_y-cam_y)*space_scale+120), 1);
		cam_star_y = (uint32_t) nearbyint(cam_y*space_scale*192);
		cam_star_x = (uint32_t) nearbyint(cam_x*space_scale*192);
		for (is=0; is<STAR_COUNT; is++)
			star_blit(screen32, (star[is].x-cam_star_x)%STAR_FIELD_SIZE, (star[is].y-cam_star_y)%STAR_FIELD_SIZE, star[is].mag);
		text_blit((uint32_t *)screen32, line1, font, 6, 8, 0, 232);
		/********************SDL Blitting********************/
		surf_array_o(screen2, screen32, 320, 240);
		SDL_UnlockSurface(screen2);
		SDL_BlitSurface(screen2, NULL, screen, NULL);
		SDL_Flip(screen);
		SDL_Delay(10);
		SDL_LockSurface(screen2);
		zeroarray((uint32_t *)screen32, 76800);	//76800 = 320 * 240
	}
printf("Distance : %.3f AU", sqrt(distance2(0, 0, rocket.pos_x, rocket.pos_y))/150000000000.0);
	SDL_FreeSurface(screen);
	chdir("/usr/gp2x");
	execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
	
	return 0;
}