#include <vectrex.h>
// does not work with any -O options. Immediately obvious when using button 1
#define abs(x) (x < 0 ? -x:x)
#define sgn(x) (x < 0 ? -1:1)
#define LAST_STAR 32
static int sx[LAST_STAR], sy[LAST_STAR];
static unsigned int sz[LAST_STAR];
static unsigned long rseed = 12345L;
static int rand (void) { // silliness.
int i = (int)Random();
if (i&16) return (int) (rseed = (rseed * 2053UL) + 13849UL);
return i;
}
int main(void) {
unsigned int star;
int x, y, x_rot_val, y_rot_val;
long tmp;
unsigned int z;
// x,y are as screen, z is 0 at a distance, 255 close-up.
int band;
for (x = 0; x < LAST_STAR; x++) {
sx[x] = (int)rand(); sy[x] = (int)rand(); sz[x] = (unsigned int)rand();
}
for (;;) {
Wait_Recal();
Reset0Ref();
VIA_t1_cnt_lo = (0x80);
Joy_Analog();
x_rot_val = Vec_Joy_1_X>>4;
y_rot_val = Vec_Joy_1_Y>>4;
star = 0;
Read_Btns();
for (star = 0; star < LAST_STAR; star++) {
x = sx[star]; y = sy[star]; z = sz[star];
if ((Vec_Btn_State&1) != 0) {
unsigned int oz = z;
// backward - stars converge into center
x = (int)(((long)x * 15L) >> 4L);
y = (int)(((long)y * 15L) >> 4L);
if ((abs(x) <= 31) && (abs(y) <= 31)) {
if (rand()&32) {
x = rand();
y = 127 * (rand()&8 ? 1 : -1);
} else {
x = 127 * (rand()&8 ? 1 : -1);
y = rand();
}
z = 254;
} else {
z -= 8;
if (sgn((int)oz) != sgn((int)z)) {
x = rand(); y = rand();
}
}
}
if ((Vec_Btn_State&2) != 0) {
unsigned int oz = z;
// forward - stars spread out away from center
tmp = ((long)x * 17L) >>4;
if (abs(tmp) > 127L) {
x = rand(); // (rand()&31)*sgn(tmp);
do {y = rand();} while (abs(y)<32); // sgn(y)*32;
z = 0;
} else {
x = (int)tmp;
z += 4;
}
tmp = ((long)y * 17L) >>4;
if (abs(tmp) > 127L) {
do {x = rand();} while (abs(x)<32); // sgn(x)*32;
y = rand(); // (rand()&31)*sgn(tmp);
z = 0;
} else {
y = (int)tmp;
z += 4;
}
if (sgn((int)oz) != sgn((int)z)) {
x = rand(); y = rand();
}
}
if ((Vec_Btn_State&4) != 0) {
// rotate clockwise
int from[2], to[2];
from[0] = y; from[1] = x;
Rot_VL_ab(1, 1, from, to);
y = to[0]; x = to[1];
}
if ((Vec_Btn_State&8) != 0) {
// rotate anti-clockwise
int from[2], to[2];
from[0] = y; from[1] = x;
Rot_VL_ab((unsigned int)-1, 1, from, to);
y = to[0]; x = to[1];
}
// movement in x or y is proportional to distance - nearer (higher 'z') = more
band = (int)((z>>5U)+1U); // 1..8
// still to modify this by analog value of joystick...
{int ox=x, oy=y;
if (x_rot_val > 4) {
x+=band;
if ((sgn(ox)>0) && (sgn(x)<0)) { y=rand(); z=(unsigned int)rand(); }
}
if (x_rot_val < -4) {
x-=band;
if ((sgn(ox)<0) && (sgn(x)>0)) { y=rand(); z=(unsigned int)rand(); }
}
if (y_rot_val > 4) {
y+=band;
if ((sgn(oy)>0) && (sgn(y)<0)) { x=rand(); z=(unsigned int)rand(); }
}
if (y_rot_val < -4) {
y-=band;
if ((sgn(oy)<0) && (sgn(y)>0)) { x=rand(); z=(unsigned int)rand(); }
}
}
sx[star] = x;
sy[star] = y;
sz[star] = z;
Reset0Ref();
VIA_t1_cnt_lo = (0x80);
Intensity_a(0x10+(unsigned int)(z>>2U)); // nearer (higher 'z') is brighter
Dot_d(y, x);
}
}
return 0;
}