/*
 * good old starfield - PASTIS 51 EDITION + CAPTAIN MOD
 * 
 * Same as starfield51 but this time we can control the origin with POT 1 and
 * POT2, which affects all the newly created stars, allowing for deep space
 * travel.
 * 
 * Really not optimised in current state, even though I tried to simplify things. 
 * But it starts to push the chip beyond its capacity, so it feels a bit sluggish now.
 * More changes would start to make the thing even less readable so...
 */
#include <TVout.h>

TVout TV;

#define STARS 51
#define POT_1 0
#define POT_2 1
#define POT_1_MOD 11 // 120/1024 ish  int(0.1171875 * 100)
#define POT_2_MOD 9  // 96/1024 ish
#define RND_1_MOD 5  // 60/1024 ish
#define RND_2_MOD 4  // 48/1024 ish

int x[STARS];
int y[STARS];
int vx[STARS];
int vy[STARS];
uint8_t ox;
uint8_t oy;
  
void
setup()
{
  randomSeed(analogRead(6));              // effective?
  TV.begin(NTSC,120,96);
  new_stars();
}

void
new_star(uint8_t i)
{
  uint8_t x_tmp, y_tmp;
  int dx, dy, pot1, pot2;
  float vl;

  pot1 = analogRead(POT_1);
  pot2 = analogRead(POT_2);
  
  ox  = pot1 * POT_1_MOD / 100 ;
  oy  = pot2 * POT_2_MOD / 100 ;
  
  x_tmp = pot1 * RND_1_MOD / 100 + random(60);
  y_tmp = pot2 * RND_2_MOD / 100 + random(48);
  
  dx = x_tmp - ox;
  dy = y_tmp - oy;

  switch(dx)
    case 0: dx = 1;                        // CHEAT
  
  vl = 1 / sqrt(dx*dx + dy*dy);
  vx[i] = int(dx * vl * 100);
  vy[i] = int(dy * vl * 100);

  x[i] = x_tmp * 100;
  y[i] = y_tmp * 100;
}

void
new_stars()
{
  for (uint8_t i = 0; i < STARS; i++)
    new_star(i);
}

void
update_stars()
{
  for (uint8_t i = 0; i < 40; i++) {
      x[i] = x[i] + vx[i];
      y[i] = y[i] + vy[i];
    if (x[i] > 12000 || x[i] < 0 || y[i] < 0 || y[i] > 9600)
      new_star(i);
  }
  for (uint8_t i = 40; i < STARS; i++) {
      x[i] = x[i] + (vx[i] << 1);
      y[i] = y[i] + (vy[i] << 1);
    if (x[i] > 12000 || x[i] < 0 || y[i] < 0 || y[i] > 9600)
      new_star(i);
  }
}

void
draw_stars()
{
  for (uint8_t i = 0; i < STARS; i++)
    TV.set_pixel(x[i]/100, y[i]/100, 1);
}

void
loop()
{
  TV.delay_frame(1);
  update_stars();
  TV.clear_screen();
  draw_stars();
}
