// *************************************************************************** // main // *************************************************************************** // This file was developed by Prof. Dr. Peer Johannsen as part of the // "Retro-Programming" and "Advanced C Programming" class at // Pforzheim University, Germany. // // It can freely be used, but at one's own risk and for non-commercial // purposes only. Please respect the copyright and credit the origin of // this file. // // Feedback, suggestions and bug-reports are welcome and can be sent to: // peer.johannsen@pforzheim-university.de // --------------------------------------------------------------------------- #include <vectrex.h> #define jsrx(v, func) asm("ldx %0\n\t" "jsr " #func "\n\t" : : "g" (v) : "d", "x") #define Draw_VLp(ra) jsrx(ra, 0xF410) // (pattern y x)* 0x01 static inline void displaylist (const int *list) { Draw_VLp (list); } static inline void wait_retrace (void) { Wait_Recal (); } static inline void set_scale (int scale) { /* VIA_t1_cnt_lo */ *(volatile int *) 0xD004 = scale; } // --------------------------------------------------------------------------- // cold reset: the vectrex logo is shown, all ram data is cleared // warm reset: skip vectrex logo and keep ram data // --------------------------------------------------------------------------- // at system startup, when powering up the vectrex, a cold reset is performed // if the reset button is pressed, then a warm reset is performed // --------------------------------------------------------------------------- // after each reset, the cartridge title is shown and then main() is called // --------------------------------------------------------------------------- // We will be updating the x and y positions in situ, and extending the array dynamically by // poking a '1' into the first element of the entry after the last active object. All // asteroids must be the same number of vectors or use moves to pad. (the Procustean option) // 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 19 #define BIG -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 MEDIUM -1,80,80, -1,80,0, -1,80,-80, -1,0,-80, -1,-80,-80, -1,-80,0, -1,-80,80, -1,0,80, 1 #define SMALL -1,60,60, -1,60,0, -1,60,-60, -1,0,-60, -1,-60,-60, -1,-60,0, -1,-60,60, -1,0,60, 1 const int vector[((unsigned long) ASTEROIDS) * 10UL * 3UL + 1UL] = { /* octagons for now, later asteroids */ /* 0 */ BIG, /* 1 */ BIG, /* 2 */ MEDIUM, /* 3 */ MEDIUM, /* 4 */ MEDIUM, /* 5 */ MEDIUM, /* 6 */ SMALL, /* 7 */ SMALL, /* 8 */ SMALL, /* 9 */ SMALL, /* 10 */ SMALL, /* 11 */ SMALL, /* 12 */ SMALL, /* 13 */ SMALL, /* 14 */ SMALL, /* 15 */ SMALL, /* 16 */ BIG, /* 17 */ BIG, /* 18 */ MEDIUM, }; int x[ASTEROIDS], y[ASTEROIDS], size2[ASTEROIDS]; int dx[ASTEROIDS * 2] = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, -1, -1, -2, -1, -1, -2, -1, -2, -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, }; int dy[ASTEROIDS * 2] = { -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 2, -2, 1, -2, 2, -2, 1, -2, 2, -2, 1, -2, 2, -1, 2, -2, 2, -2, }; static unsigned long rseed; static int random (void) { // VECTREX HAS A BUILT-IN RANDOM THAT WE CAN USE! // (though it doesn't seem very good - this may be better and faster) return (int) (rseed = (rseed * 2053UL) + 13849UL); } int main (void) { int base, row, tmp1; // , tmp2, other, diffx, diffy; int *vec; vec = (int *) (vector + 3); for (row = 0; row < ASTEROIDS; row++) { x[row] = random (); y[row] = random (); size2[row] = *vec * *vec; vec += 3 * 8 + 1; } base = 0; for (;;) { Wait_Recal (); vec = (int *) vector; for (row = 0; row < ASTEROIDS; row++) { Reset0Ref (); Intensity_a (0x7f); set_scale (0x58); Moveto_d (y[row], x[row]); set_scale (0x01); displaylist (vec); vec += 3 * 8 + 1; } // now move asteroids around for (row = 0; row < ASTEROIDS; row++) { // Bounce off walls? Marginally more expensive than wrapping. tmp1 = x[row] + dx[base + row]; if ((dx[base + row] > 0 && x[row] > 0 && tmp1 < 0) || (dx[base + row] < 0 && x[row] < 0 && tmp1 > 0)) { dx[base + row] = -dx[base + row]; } else { x[row] = tmp1; } tmp1 = y[row] + dy[base + row]; if ((dy[base + row] > 0 && y[row] > 0 && tmp1 < 0) || (dy[base + row] < 0 && y[row] < 0 && tmp1 > 0)) { dy[base + row] = -dy[base + row]; } else { y[row] = tmp1; } // Bump asteroid? #ifdef NEVER for (other = row + 1; other < ASTEROIDS; other++) { tmp1 = x[row] ^ x[other]; tmp2 = y[row] ^ y[other]; if ((tmp1 < 0) || (tmp2 < 0)) { diffx = x[row] - x[other]; diffy = y[row] - y[other]; diffx *= diffx; diffy *= diffy; if (diffx + diffy < size2[row] + size2[other]) { if (tmp1 < 0) dx[row] = -dx[row]; if (tmp2 < 0) dy[row] = -dy[row]; } } } #endif } base ^= ASTEROIDS; } // if return value is <= 0, then a warm reset will be performed, // otherwise a cold reset will be performed return 0; } // *************************************************************************** // end of file // ***************************************************************************