Forum Replies Created
Viewing 1 post (of 1 total)
-
AuthorPosts
-
SG57Member
OK finally got my $2 breakout board from China, debugged my horrible code and got the starfield working. I had a few oversights coming from platforms that had better hardware, such as bytes being unsigned, string literals being costly and structures add up when you have a lot of them. I tuned the constants just below artifacts began appearing. I suppose lowering the resolution would allow more stars onscreen but for now 16 still creates the effect.
In anycase, here is the working final code, its your typical Starfield/hyperspace view thing with stars wizzing by in pseudo-3D. you can adjust the Speed with up/down on the on-board controller.
/** Starfield for Hackvision
By Cord Rehn 2012 **/
#include
#include
#include
#include
#include
#define TV_W 136
#define TV_H 98
TVout tv;
#define NUM_STARS 16
#define Z_MAX 6.f
byte SPEED;
char speed_string[11], s[4];
prog_char s0[] PROGMEM = "SPEED ";
PROGMEM const char *strings[] = {s0};
struct Star {
int x, y;
byte old_x, old_y;
float z;
} Starfield[NUM_STARS];
void initStar(int index) {
Starfield[index].x = random(TV_W*2) - TV_W;
Starfield[index].y = random(TV_H*2) - TV_H;
Starfield[index].old_x = Starfield[index].old_y = 255;
Starfield[index].z = Z_MAX;
}
void setSpeed(byte speed) {
tv.tone(speed < SPEED ? 800 : 1046, 20);
SPEED = speed;
speed_string[0] = s[0] = ' ';
strcpy_P(speed_string, (char *)pgm_read_word(&(strings[0])));
snprintf(s, 4, "%d ", SPEED); // 2 spaces are important, clears the 2nd and 3rd digit spots for a 1 digit speed when printed
strncat(speed_string, s, 11);
}
void setup() {
// If pin 12 is pulled LOW, then the PAL jumper is shorted.
pinMode(12, INPUT);
digitalWrite(12, HIGH);
if (digitalRead(12) == LOW)
tv.begin(_PAL, TV_W, TV_H);
else
tv.begin(_NTSC, TV_W, TV_H);
tv.select_font(font4x6);
randomSeed(analogRead(0));
tv.delay(10);
// init star field
for (int i = 0; i < NUM_STARS; ++i) {
initStar(i);
Starfield.z = random(Z_MAX+1);
}
setSpeed(100);
}
void loop() {
// input
if (Controller.upPressed() && SPEED != 255)
setSpeed(SPEED + 1);
else if (Controller.downPressed() && SPEED != 0)
setSpeed(SPEED - 1);
// draw
for (int i = 0; i < NUM_STARS; ++i) {
if (Starfield.old_x != 255)
tv.set_pixel(Starfield.old_x, Starfield.old_y, 0);
Starfield.z -= (float)SPEED/1000.f;
if (Starfield.z < (float)SPEED/1000.f)
initStar(i);
byte x = TV_W / 2 + Starfield.x / Starfield.z,
y = TV_H / 2 + Starfield.y / Starfield.z;
if (x < 0 || y < 0 || x >= TV_W || y >= TV_H)
initStar(i);
else {
tv.set_pixel(x, y, 1);
Starfield.old_x = x;
Starfield.old_y = y;
}
}
tv.print(0, 0, speed_string);
}
-
AuthorPosts
Viewing 1 post (of 1 total)