/* * good old starfield - PASTIS 51 EDITION * * See starfield25 for context and more comments, otherwise it may not make much * sense... * * So basically the trick used to get more stars here, is not to free memory, * because that's not possible, but instead it's to make the stars use less memory. * To do that we change the type from float (4 bytes) to int (2 bytes). * The tradeoff is of course that now we have integers and not floating point numbers, * and that prevents us to have any meaningful results when we calculate vector related * stuff. But there's a workaround to this! * The workaround is very simple, we use int as floats without floating points, which * means that everytime we read from the array we convert the int to float and divide * it by an arbitrary precision value (here we use 100), and when we want to store a * float we multiply it by the same precision value and convert to int. * We loose in accuray, but that does not matter here at all. * * ex: we want to store 12,345678 * 12,3456 * 100 = 1234,56 * int(1234,56) = 1234 * and converted back * float(1234 / 100) = 12,34 * in the process with this trick we lost 0,005678 (who cares?) * * Note: most of the changes are in new_star(). There are some minor changes elsewhere, * mostly to try optimise things cheaply, ignore. */ #include TVout TV; #define STARS 51 int x[STARS]; int y[STARS]; int vx[STARS]; int vy[STARS]; 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; uint8_t ox = 60; uint8_t oy = 48; int dx, dy; float vl; x_tmp = 30 + random(60); y_tmp = 24 + 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(); }