// make the move/remove into a single separate ram array
// and just have one copy of each asteroid. use pointers to it...
// (although that stops working when we use rotation)

#define ASTEROIDS 24

void intro(void) {
  static const int white_big[] = {
  // 0,   0,   0,  // adjustment for corner/center!
    -1, 120, 120, -1, 120,0,  -1, 120,-120, -1,0,-120,
    -1,-120,-120, -1,-120,0,  -1,-120, 120, -1,0, 120,
    1
  };
#define XX 14
#define YY 14
// using a copy of dx,dy means that this code can be merged with
// 'Draft4' and used before the initialisation; overlaying dx and dy
// on top of the stack.
  const int8_t cdx[ASTEROIDS] = {
     1,1,1,1, 2,2,2,2, -1,-1,-1,-1, -2,-2,-2,-2, 1,2,-2,-1, 1,2,-2,-1
  };
  const int8_t cdy[ASTEROIDS] = {
     -2,-1,1,2,  -2,-1,1,2,  -2,-1,1,2,  -2,-1,1,2, -2,1,1,2, -1,-2,2,1
  };
  int8_t dx[ASTEROIDS], dy[ASTEROIDS];
  int8_t x[ASTEROIDS], y[ASTEROIDS];
#define MARGIN 20
   uint8_t direction=0;
   int8_t done;
   int8_t base, row, tmp1;		// , tmp2, other, diffx, diffy;
   //int8_t xtarget, ytarget;

   for (row = 0; row < ASTEROIDS; row++) {
     dx[row]=cdx[row]; dy[row]=cdy[row];
   }
   row=0;
   {int xx,yy; // lay out the initial board position for the animation:
     for (yy = 1; yy <= 8; yy++) {
       if (yy != 4 && yy != 5) {
         for (xx = ((yy&1)^1)+1; xx <=8; xx+=2) {x[row] = (xx-4)*2*XX-XX; y[row++] = (yy-4)*2*YY-YY;}
       }
     }
    }

   base = 0; direction = 0;
   do {
      // now move asteroids around invisibly and quickly
      for (row = 0; row < ASTEROIDS; row++) {
        // Bounce off walls? Marginally more expensive than wrapping.
        tmp1 = x[row] + dx[base + row]; // overflow test
        if ((dx[base + row] > 0 && x[row] > 0 && (int8_t)(tmp1+MARGIN) < 0)
          || (dx[base + row] < 0 && x[row] < 0 && (int8_t)(tmp1-MARGIN) > 0)) {
          dx[base + row] = -dx[base + row]; // bounce?
        }
        x[row] = x[row] + dx[base + row];
        
        tmp1 = y[row] + dy[base + row];
        if ((dy[base + row] > 0 && y[row] > 0 && (int8_t)(tmp1+MARGIN) < 0)
          || (dy[base + row] < 0 && y[row] < 0 && (int8_t)(tmp1-MARGIN) > 0)) {
          dy[base + row] = -dy[base + row];
        }
        y[row] = y[row] + dy[base + row];
      }
      //base ^= ASTEROIDS;
      direction++;
   } while (direction != 255); // change constant depending on length and complexity of animation

   // reverse the movement vectors
   for (tmp1 = 0; tmp1 < ASTEROIDS; tmp1++) {
     dx[tmp1] = -dx[tmp1];  dy[tmp1] = -dy[tmp1];
   }

   // visibly unwind...
   do {
      direction--;
      //base ^= ASTEROIDS;

      // now move asteroids around
      for (row = 0; row < ASTEROIDS; row++) {
        // Bounce off walls? Marginally more expensive than wrapping.
        tmp1 = x[row] + dx[base + row]; // overflow test
        if ((dx[base + row] > 0 && x[row] > 0 && (int8_t)(tmp1+MARGIN) < 0)
          || (dx[base + row] < 0 && x[row] < 0 && (int8_t)(tmp1-MARGIN) > 0)) {
          dx[base + row] = -dx[base + row]; // bounce?
        }
        x[row] = x[row] + dx[base + row];
        
        tmp1 = y[row] + dy[base + row];
        if ((dy[base + row] > 0 && y[row] > 0 && (int8_t)(tmp1+MARGIN) < 0)
          || (dy[base + row] < 0 && y[row] < 0 && (int8_t)(tmp1-MARGIN) > 0)) {
          dy[base + row] = -dy[base + row];
        }
        y[row] = y[row] + dy[base + row];

      }
      Wait_Recal (); Flash++;
      Display_board(0);
      Intensity_a (WHITE_INTENSITY);
      for (row = 0; row < ASTEROIDS; row++) {
        Reset0Ref ();
        set_scale (MEDIUM_SCALE);
        Moveto_d (y[row]-11, x[row]-1);
        set_scale (TINY_SCALE);
        if (row == 12) Intensity_a (BLACK_INTENSITY);
#ifdef PIZERO
        Draw_Line_d(120,120);
        Draw_Line_d(120,0);
        Draw_Line_d(120,-120);
        Draw_Line_d(0,-120);
        Draw_Line_d(-120,-120);
        Draw_Line_d(-120,0);
        Draw_Line_d(-120,120);
        Draw_Line_d(0,120);
#else
        Draw_VLp((int8_t *)white_big);
#endif
      }

   } while (direction);

    (void)tmp1;(void)base;(void)done;(void)direction; // freeze result
    direction = 24;
    while (--direction != 0) {
      Wait_Recal (); Flash++;
      Display_board(0);
      Intensity_a (WHITE_INTENSITY); // use the constant (name?)
      for (row = 0; row < ASTEROIDS; row++) {
        Reset0Ref ();
        set_scale (MEDIUM_SCALE);
        Moveto_d (y[row]-11, x[row]-1);
        set_scale (TINY_SCALE);
        if (row == 12) Intensity_a (BLACK_INTENSITY);
#ifdef ORIGINAL
        Draw_VLp ((int8_t *)white_big);
#else
	Draw_Line_d(120,120);
	Draw_Line_d(120,0);
	Draw_Line_d(120,-120);
	Draw_Line_d(0,-120);
	Draw_Line_d(-120,-120);
	Draw_Line_d(-120,0);
	Draw_Line_d(-120,120);
	Draw_Line_d(0,120);
#endif
      }
    }
#undef XX
#undef YY
}