#include <vectrex.h> // next try - remove ships, use simple triangle or square or cross static long DebugValue = 0; #define MAX_RAM 208L #define MAX_LINE (MAX_RAM/4L) // At this stage we can handle 52 vectors unsigned int next_point = 0; long FromX[MAX_LINE]; long FromY[MAX_LINE]; long ToX[MAX_LINE]; long ToY[MAX_LINE]; long intFrameNo = 0L; // 16 bits, enough for 16K/50 seconds long fgFrameNo = 0L; typedef long fp14; // 16 bits on Vectrex //---------------------------------------------- // // 2.14 fixed point sine and cosine tables. // // These table assume that there are 256 angles // in a circle. // static const fp14 sine[256L] __attribute__ ((section(".text"))) = { 0, 402, 803, 1205, 1605, 2005, 2404, 2801, 3196, 3589, 3980, 4369, 4756, 5139, 5519, 5896, 6269, 6639, 7005, 7366, 7723, 8075, 8423, 8765, 9102, 9434, 9759, 10079, 10393, 10701, 11002, 11297, 11585, 11866, 12139, 12406, 12665, 12916, 13159, 13395, 13622, 13842, 14053, 14255, 14449, 14634, 14810, 14978, 15136, 15286, 15426, 15557, 15678, 15790, 15892, 15985, 16069, 16142, 16206, 16260, 16305, 16339, 16364, 16379, 16384, 16379, 16364, 16339, 16305, 16260, 16206, 16142, 16069, 15985, 15892, 15790, 15678, 15557, 15426, 15286, 15136, 14978, 14810, 14634, 14449, 14255, 14053, 13842, 13622, 13395, 13159, 12916, 12665, 12406, 12139, 11866, 11585, 11297, 11002, 10701, 10393, 10079, 9759, 9434, 9102, 8765, 8423, 8075, 7723, 7366, 7005, 6639, 6269, 5896, 5519, 5139, 4756, 4369, 3980, 3589, 3196, 2801, 2404, 2005, 1605, 1205, 803, 402, 0, -402, -803, -1205, -1605, -2005, -2404, -2801, -3196, -3589, -3980, -4369, -4756, -5139, -5519, -5896, -6269, -6639, -7005, -7366, -7723, -8075, -8423, -8765, -9102, -9434, -9759, -10079, -10393, -10701, -11002, -11297, -11585, -11866, -12139, -12406, -12665, -12916, -13159, -13395, -13622, -13842, -14053, -14255, -14449, -14634, -14810, -14978, -15136, -15286, -15426, -15557, -15678, -15790, -15892, -15985, -16069, -16142, -16206, -16260, -16305, -16339, -16364, -16379, -16384, -16379, -16364, -16339, -16305, -16260, -16206, -16142, -16069, -15985, -15892, -15790, -15678, -15557, -15426, -15286, -15136, -14978, -14810, -14634, -14449, -14255, -14053, -13842, -13622, -13395, -13159, -12916, -12665, -12406, -12139, -11866, -11585, -11297, -11002, -10701, -10393, -10079, -9759, -9434, -9102, -8765, -8423, -8075, -7723, -7366, -7005, -6639, -6269, -5896, -5519, -5139, -4756, -4369, -3980, -3589, -3196, -2801, -2404, -2005, -1605, -1205, -803, -402, }; typedef struct VPoint { long x,y,z; // at least until these are scaled down... } VPoint; long mult_sin(long x, unsigned int angle) { long long product; product = x * sine[angle]; product >>= 14L; return (long)product; } long mult_cos(long x, unsigned int angle) { long long product; angle += 64; product = x * sine[angle]; product >>= 14L; return (long)product; } // x,y,z - 'real' world (1024x1024x1024) // xangle,yangle,zangle - rotate object around its own axis (note: need quaternions to avoid gimbal lock) // screenx, screeny, screenz - 'virtual pixel' offset in screen coords (1280x1024) void DrawShip(int ship, long x, long y, long z, unsigned int xangle, unsigned int yangle, unsigned int zangle, int screenx, int screeny, int PreMul, int PreDiv) { // Battlezone objects reverse-engineered by Nicholas Bond - many thanks. // http://www.retrogamedeconstructionzone.com/2020/04/battlezone-modelling-3-d-vector-baddies.html // Original data was given to me as doubles (eg lines of 1.5 length) but I've scaled everything to ints #define nNumVectors0 1 //42 static const VPoint vectors0[nNumVectors0*2] __attribute__ ((section(".text"))) = { { 44, 0, 373 }, { 144, 0, 373 }, /* { 144, 0, 373 }, { 144, 0, 473 }, { 144, 0, 473 }, { 44, 0, 473 }, { 44, 0, 473 }, { 44, 0, 373 }, { 44, 0, 373 }, { 76, 58, 405 }, { 76, 58, 405 }, { 111, 58, 405 }, { 111, 58, 405 }, { 111, 58, 437 }, { 111, 58, 437 }, { 76, 58, 437 }, { 76, 58, 437 }, { 76, 58, 405 }, { 144, 0, 373 }, { 111, 58, 405 }, { 144, 0, 473 }, { 111, 58, 437 }, { 44, 0, 473 }, { 76, 58, 437 }, { 0, 124, 423 }, { 32, 58, 423 }, { 32, 58, 423 }, { 155, 58, 423 }, { 155, 58, 423 }, { 187, 124, 423 }, { 187, 124, 423 }, { 155, 182, 423 }, { 155, 182, 423 }, { 32, 182, 423 }, { 32, 182, 423 }, { 0, 124, 423 }, { 0, 124, 423 }, { 93, 124, 0 }, { 32, 58, 423 }, { 93, 124, 0 }, { 155, 58, 423 }, { 93, 124, 0 }, { 187, 124, 423 }, { 93, 124, 0 }, { 155, 182, 423 }, { 93, 124, 0 }, { 32, 182, 423 }, { 93, 124, 0 }, { 53, 124, 523 }, { 74, 90, 523 }, { 74, 90, 523 }, { 116, 90, 523 }, { 116, 90, 523 }, { 137, 124, 523 }, { 137, 124, 523 }, { 116, 158, 523 }, { 116, 158, 523 }, { 74, 158, 523 }, { 74, 158, 523 }, { 53, 124, 523 }, { 53, 124, 523 }, { 0, 124, 423 }, { 74, 90, 523 }, { 32, 58, 423 }, { 116, 90, 523 }, { 155, 58, 423 }, { 137, 124, 523 }, { 187, 124, 423 }, { 116, 156, 523 }, { 155, 184, 423 }, { 74, 156, 523 }, { 32, 184, 423 }, { 62, 156, 212 }, { 118, 156, 212 }, { 118, 156, 212 }, { 90, 184, 423 }, { 90, 184, 423 }, { 62, 156, 212 }, { 62, 156, 212 }, { 90, 223, 395 }, { 90, 223, 395 }, { 118, 156, 212 }, { 90, 223, 395 }, { 90, 184, 423 }, */ }; #define nNumVectors1 1 // 33 static const VPoint vectors1[nNumVectors1*2] __attribute__ ((section(".text"))) = { { 176, 0, 147 }, { 216, 0, 147 }, /* { 216, 0, 147 }, { 245, 0, 176 }, { 245, 0, 176 }, { 245, 0, 216 }, { 245, 0, 216 }, { 216, 0, 245 }, { 216, 0, 245 }, { 176, 0, 245 }, { 176, 0, 245 }, { 147, 0, 216 }, { 147, 0, 216 }, { 147, 0, 176 }, { 147, 0, 176 }, { 176, 0, 147 }, { 176, 0, 147 }, { 116, 49, 0 }, { 116, 49, 0 }, { 276, 49, 0 }, { 276, 49, 0 }, { 392, 49, 116 }, { 392, 49, 116 }, { 392, 49, 276 }, { 392, 49, 276 }, { 276, 49, 392 }, { 276, 49, 392 }, { 116, 49, 392 }, { 116, 49, 392 }, { 0, 49, 276 }, { 0, 49, 276 }, { 0, 49, 116 }, { 0, 49, 116 }, { 116, 49, 0 }, { 176, 0, 147 }, { 116, 49, 0 }, { 116, 49, 0 }, { 196, 151, 196 }, { 216, 0, 147 }, { 276, 49, 0 }, { 276, 49, 0 }, { 196, 151, 196 }, { 245, 0, 176 }, { 392, 49, 116 }, { 392, 49, 116 }, { 196, 151, 196 }, { 245, 0, 216 }, { 392, 49, 276 }, { 392, 49, 276 }, { 196, 151, 196 }, { 216, 0, 245 }, { 276, 49, 392 }, { 276, 49, 392 }, { 196, 151, 196 }, { 176, 0, 245 }, { 116, 49, 392 }, { 116, 49, 392 }, { 196, 151, 196 }, { 147, 0, 216 }, { 0, 49, 276 }, { 0, 49, 276 }, { 196, 151, 196 }, { 147, 0, 176 }, { 0, 49, 116 }, { 0, 49, 116 }, { 196, 151, 196 }, */ }; #define nNumVectors2 7 // 30 static const VPoint vectors2[nNumVectors2*2] __attribute__ ((section(".text"))) = { { 0, 0, 0 }, { 71, 0, 0 }, { 71, 0, 0 }, { 64, 0, 129 }, { 64, 0, 129 }, { 12, 0, 129 }, { 12, 0, 129 }, { 0, 0, 0 }, { 0, 0, 0 }, { 8, 33, 0 }, { 8, 33, 0 }, { 65, 33, 0 }, { 65, 33, 0 }, { 71, 0, 0 },/* { 8, 33, 0 }, { 12, 0, 129 }, { 65, 33, 0 }, { 64, 0, 129 }, { 36, 5, 107 }, { 19, 29, 15 }, { 19, 29, 15 }, { 19, 33, 0 }, { 19, 33, 0 }, { 24, 53, 0 }, { 24, 53, 0 }, { 47, 53, 0 }, { 47, 53, 0 }, { 53, 33, 0 }, { 53, 33, 0 }, { 53, 29, 15 }, { 53, 29, 15 }, { 36, 5, 107 }, { 36, 5, 107 }, { 24, 53, 15 }, { 24, 53, 15 }, { 47, 53, 15 }, { 47, 53, 15 }, { 36, 5, 107 }, { 47, 53, 15 }, { 47, 53, 0 }, { 24, 53, 15 }, { 24, 53, 0 }, { 30, 39, 118 }, { 43, 39, 118 }, { 43, 39, 118 }, { 43, 45, 118 }, { 43, 45, 118 }, { 30, 45, 118 }, { 30, 45, 118 }, { 30, 39, 118 }, { 30, 39, 118 }, { 30, 39, 40 }, { 43, 39, 118 }, { 43, 39, 40 }, { 43, 45, 118 }, { 43, 45, 30 }, { 30, 45, 118 }, { 30, 45, 30 }, { 36, 53, 0 }, { 36, 82, 0 }, */ }; #define nNumVectors3 1 // 47 static const VPoint vectors3[nNumVectors3*2] __attribute__ ((section(".text"))) = { { 6, 0, 20 }, { 78, 0, 20 }, /* { 78, 0, 20 }, { 78, 0, 137 }, { 78, 0, 137 }, { 6, 0, 137 }, { 6, 0, 137 }, { 6, 0, 20 }, { 6, 0, 20 }, { 0, 17, 0 }, { 0, 17, 0 }, { 84, 17, 0 }, { 84, 17, 0 }, { 84, 17, 157 }, { 84, 17, 157 }, { 0, 17, 157 }, { 0, 17, 157 }, { 0, 17, 0 }, { 0, 17, 0 }, { 18, 32, 40 }, { 18, 32, 40 }, { 68, 32, 40 }, { 68, 32, 40 }, { 68, 32, 135 }, { 68, 32, 135 }, { 18, 32, 135 }, { 18, 32, 135 }, { 18, 32, 40 }, { 18, 32, 40 }, { 32, 54, 119 }, { 32, 54, 119 }, { 53, 54, 119 }, { 53, 54, 119 }, { 68, 32, 135 }, { 68, 32, 135 }, { 84, 17, 157 }, { 84, 17, 157 }, { 78, 0, 137 }, { 6, 0, 137 }, { 0, 17, 157 }, { 0, 17, 157 }, { 18, 32, 135 }, { 18, 32, 135 }, { 32, 54, 119 }, { 78, 0, 20 }, { 84, 17, 0 }, { 84, 17, 0 }, { 68, 32, 40 }, { 68, 32, 40 }, { 53, 54, 119 }, { 38, 42, 12 }, { 47, 42, 12 }, { 47, 42, 12 }, { 47, 48, 12 }, { 47, 48, 12 }, { 38, 48, 12 }, { 38, 48, 12 }, { 38, 42, 12 }, { 38, 42, 12 }, { 38, 42, 79 }, { 47, 42, 12 }, { 47, 42, 79 }, { 47, 48, 12 }, { 47, 48, 100 }, { 38, 48, 12 }, { 38, 48, 100 }, { 6, 3, 18 }, { 79, 3, 18 }, { 3, 9, 10 }, { 81, 9, 10 }, { 41, 54, 120 }, { 41, 58, 120 }, { 41, 58, 120 }, { 36, 58, 120 }, { 36, 58, 120 }, { 30, 62, 115 }, { 30, 62, 115 }, { 30, 64, 115 }, { 30, 64, 115 }, { 36, 68, 120 }, { 36, 68, 120 }, { 46, 68, 120 }, { 46, 68, 120 }, { 52, 64, 115 }, { 52, 64, 115 }, { 52, 62, 115 }, { 52, 62, 115 }, { 46, 58, 120 }, { 46, 58, 120 }, { 41, 58, 120 }, { 46, 58, 120 }, { 46, 68, 120 }, { 36, 58, 120 }, { 36, 68, 120 }, */ }; static const unsigned int nvec[4] = {nNumVectors0,nNumVectors1,nNumVectors2,nNumVectors3}; // The pvec array initialisation below caused LCC to crash: // so rather than have 'ifdef's for one compiler, I rewrote it as an explicit initialisation. static const VPoint *pvec[4] = {vectors0, vectors1, vectors2, vectors3}; static unsigned int i, nNumVectors; nNumVectors = nvec[ship]; DebugValue=1; for (i=0; i<nNumVectors*2; i+=2) { static long x0, y0, z0, x1, y1, z1, tx0, ty0, tz0, tx1, ty1, tz1, xa, ya, xb, yb; DebugValue=i; x0 = pvec[ship][i].x; // *(long long)PreMul) ///(long)PreDiv) ; // last minute rescaling as the ships looked a little DebugValue=6662; y0 = pvec[ship][i].y; // *(long long)PreMul) ///(long)PreDiv) ; // too large when entering space on the back plane. DebugValue=6663; z0 = pvec[ship][i].z; // *(long long)PreMul) ///(long)PreDiv) ; // remove this later... rescale the data or fix it when we move to OpenGL matrices DebugValue=6664; (void)PreMul;(void)PreDiv; DebugValue=6665; x1 = pvec[ship][i+1].x; // *(long long)PreMul)/(long)PreDiv) ; DebugValue=6666; y1 = pvec[ship][i+1].y; // *(long long)PreMul)/(long)PreDiv) ; DebugValue=6670; z1 = pvec[ship][i+1].z; // *(long long)PreMul)/(long)PreDiv) ; DebugValue=6671; // rotate around z if (zangle) { DebugValue=6672; tx0 = mult_cos(x0, zangle)-mult_sin(y0, zangle); DebugValue=6673; ty0 = mult_sin(x0, zangle)+mult_cos(y0, zangle); tz0 = z0; DebugValue=6674; tx1 = mult_cos(x1, zangle)-mult_sin(y1, zangle); ty1 = mult_sin(x1, zangle)+mult_cos(y1, zangle); tz1 = z1; x0=tx0;y0=ty0;z0=tz0; x1=tx1;y1=ty1;z1=tz1; } DebugValue=668; // rotate around y if (yangle) { tz0 = mult_cos(z0, yangle)-mult_sin(x0, yangle); tx0 = mult_sin(z0, yangle)+mult_cos(x0, yangle); ty0 = y0; tz1 = mult_cos(z1, yangle)-mult_sin(x1, yangle); tx1 = mult_sin(z1, yangle)+mult_cos(x1, yangle); ty1 = y1; x0=tx0;y0=ty0;z0=tz0; x1=tx1;y1=ty1;z1=tz1; } DebugValue=6691; // rotate around x if (xangle) { DebugValue=6692; ty0 = mult_cos(y0, xangle)-mult_sin(z0, xangle); tz0 = mult_sin(y0, xangle)+mult_cos(z0, xangle); tx0 = x0; DebugValue=6693; ty1 = mult_cos(y1, xangle)-mult_sin(z1, xangle); tz1 = mult_sin(y1, xangle)+mult_cos(z1, xangle); tx1 = x1; DebugValue=6694; tx0 = tx0+x; ty0 = ty0+y; tx1 = tx1+x; ty1 = ty1+y; x0=tx0;y0=ty0;z0=tz0; x1=tx1;y1=ty1;z1=tz1; } DebugValue=6695; x0 += x; y0 += y; x1 += x; y1 += y; #define TWEAK 1024L /* was 1024 */ DebugValue=658; if ((TWEAK+z0) == 1024) { xa = (long)((TWEAK*(long long)x0) >> 10); } else { if (x0 == 0) xa = 0; else xa = (long)( (long)(TWEAK*(long)x0) / (long)(TWEAK+z0) // INTERRUPT CODE HANGS HERE ); } DebugValue=659; if ((TWEAK+z0) == 1024) { ya = (long)((TWEAK*(long long)y0) >> 10); } else { if (y0 == 0) ya = 0; else ya = (long)( (long)(TWEAK*(long)y0) / (long)(TWEAK+z0) // INTERRUPT CODE HANGS HERE ); } //ya = (long)((TWEAK*(long long)y0) / (TWEAK+z0)); DebugValue=660; if ((TWEAK+z1) == 1024 || 1) { xb = (long)((TWEAK*(long long)x1) >> 10); } else { if (x1 == 0) xb = 0; else xb = (long)( (long)(TWEAK*(long)x1) / (long)(TWEAK+z1) // INTERRUPT CODE HANGS HERE ); } DebugValue=671; if ((TWEAK+z1) == 1024) { yb = (long)((TWEAK*(long)y1) >> 10); } else { if (y1 == 0) yb = 0; else yb = (long)( (long)(TWEAK*(long)y1) / (long)(TWEAK+z1) // INTERRUPT CODE HANGS HERE ); } //yb = (long)((TWEAK*(long long)y1) / (TWEAK+z1)); DebugValue=672; // scale by depth ">>10" is short for "/ZDEPTH" (if ZDEPTH==1024) z += 200; xa *= z; z -= 200; xa >>= 10L; //xa = (long)((long)xa*(z+200L))>>10; DebugValue=6730; z += 200; ya *= z; z -= 200; ya >>= 10L; //ya = (long)((long)ya*(z+200L))>>10; DebugValue=6731; z += 200; xb *= z; z -= 200; xb >>= 10L; //xb = (long)((long)xb*(z+200L))>>10; DebugValue=6732; z += 200; yb *= z; z -= 200; yb >>= 10L; //yb = (long)((long)yb*(z+200L))>>10; DebugValue=674; xa += screenx; ya += screeny; xb += screenx; yb += screeny; // v_line(400+xa+screenx,400+ya+screeny,400+xb+screenx,400+yb+screeny, 64); DebugValue=675; FromX[next_point] = (int)(xa); FromY[next_point] = (int)(ya); ToX[next_point] = (int)(xb); ToY[next_point] = (int)(yb); next_point += 1; } DebugValue=1000; // 1000 means drawships has exited #undef nNumVectors0 #undef nNumVectors1 #undef nNumVectors2 #undef nNumVectors3 } #define int8_t int #define uint8_t unsigned int #define int16_t long #define uint16_t unsigned long #define int32_t long long #define uint32_t unsigned long long #ifndef TRUE #define TRUE (0==0) #define FALSE (0!=0) #endif #define NULL 0 static unsigned int dotmask = 0xC3; #define DRAWING_SCALE 0x80 #define CROSSHAIR_SCALE 0x40 #define set_scale(s) do { VIA_t1_cnt_lo = s; } while (0) #define BRIGHT TRUE #define normal FALSE static unsigned char patList[2]; static void drawline_patterned (int y, int x, unsigned char pat) { patList[0] = (unsigned char) y; patList[1] = (unsigned char) x; *(volatile unsigned char *) 0xC829 = pat; *(volatile unsigned char *) 0xC823 = 0; Draw_Pat_VL (patList); } static int last_intensity = -128; static void drawline (long x1, long y1, long x2, long y2, int bright, int dashed) { // autoscale to 8 bits signed! long dx, dy; int shift = 0; for (;;) { if ( (((x1 >> (shift+8)) == -1L) || ((x1 >> (shift+8)) == 0L)) && (((y1 >> (shift+8)) == -1L) || ((y1 >> (shift+8)) == 0L)) && (((x2 >> (shift+8)) == -1L) || ((x2 >> (shift+8)) == 0L)) && (((y2 >> (shift+8)) == -1L) || ((y2 >> (shift+8)) == 0L)) ) break; shift += 1; if (shift == 8) { shift = 0; break; // OOPS. } } if (shift) { x1 >>= shift; y1 >>= shift; x2 >>= shift; y2 >>= shift; } if (bright) { if (last_intensity != BRIGHT) Intensity_7F (); } else { if (last_intensity != normal) Intensity_3F (); } last_intensity = bright; Reset0Ref (); set_scale (DRAWING_SCALE); dx = ((long) x2 - (long) x1); dy = ((long) y2 - (long) y1); Moveto_d ((int) y1, (int) x1); // id dx is 255, it splits into 127 and 128 - which causes a problem // because +128 is not possible if (dy == 255 || dx == 255) { // 255-unit long lines are split in three, all others are split in two. drawline_patterned ((int) (dy / 3L), (int) (dx / 3L), (dashed ? dotmask : 0xFF)); dy -= dy / 3L; dx -= dx / 3L; } if (dy < -128L || dy > 127L || dx < -128L || dx > 127L) { drawline_patterned ((int) (dy >> 1L), (int) (dx >> 1L), (dashed ? dotmask : 0xFF)); // don't care which way it rounds (>>1 or /2) because this picks up the // odd bit: dy -= dy >> 1L; dx -= dx >> 1L; } drawline_patterned ((int) dy, (int) dx, (dashed ? dotmask : 0xFF)); } static char *mystrdup (const char *s) { // to ensure writable strings in 'assign' procedure // No heap on vectrex, so this is a little hacky. // Fortunately I know we never have more than // one 'heap' string at a time... static char copy[255U], *t; // has to be large enough for biggest problem // string in layouts.h unsigned int len; t = copy; len = 0; do { len += 1; if (len == 255) { for (;;) ; // halt. } *t++ = *s++; } while (*s != '\0'); *t = '\0'; return copy; } static char *mystrchr (char *s, char ch) { if (!s) return NULL; for (;;) { if (*s == '\0') return NULL; if (*s == ch) return s; s += 1; } } static int atoui (const char *s) { // we know all inputs are unsigned int i = 0, c; if (!s) return i; for (;;) { if (*s == '\0') return i; c = (int) *s++; if (c < '0') break; if (c > '9') break; c = c - '0'; i = i * 10 + c; } return i; } static uint8_t _x, _a, _b, _c; static void initRandom (unsigned int s1, unsigned int s2, unsigned int s3, unsigned int x0) { _x = x0; _a = s1; _b = s2; _c = s3; _x++; _a = (_a ^ _c ^ _x); _b = (_b + _a); _c = ((_c + (_b >> 1)) ^ _a); } static uint8_t random8 (void) { // assert returns unsigned value that fits in // an int. _x++; _a = (_a ^ _c ^ _x); _b = (_b + _a); _c = ((_c + (_b >> 1)) ^ _a); return _c; } #define IRQ_6809_MASK 0x10 #define ENABLE_IRQ_6809 asm("andcc #0xef") #define DISABLE_IRQ_6809 asm("orcc #0x10") // does not return, since we use the // actual waitRecal "shortcut" to jump to "set_refresh" and return from there __attribute__ ((noinline)) void iWaitRecal (void) { // if inlined, the JMP -> RTS goes astray!!! Vec_Loop_Count++; // I assume EVERYTHING is done with DP = D0 // BSR DP_to_D0 ;DP to I/O asm ("jmp 0xF1A2"); // Set_Refresh } static void SHOW_NUM(char *dest, long num) { // left-aligned #define show_digit(x) *dest++ = (char)((x)+'0') int8_t digit, zeroes; // This replaces code that used divide by 10 and modulo 10. Much faster. // handles full 16 bit range of -32768:32767 - Uses negative numbers to avoid the issue of negating -32768 if (num >= 0) num = -num; else *dest++ = '-'; digit = 0; zeroes = 1; // CLRing is shorter // max 11 add/subtracts... if (num <= -20000) { num += 20000; digit += 2; zeroes = 0; } if (num <= -10000) { num += 10000; digit += 1; zeroes = 0; } if (!zeroes) show_digit(digit); digit = 0; if (num <= -8000) { num += 8000; digit += 8; zeroes = 0; } else if (num <= -4000) { num += 4000; digit += 4; zeroes = 0; } if (num <= -2000) { num += 2000; digit += 2; zeroes = 0; } if (num <= -1000) { num += 1000; digit += 1; zeroes = 0; } if (!zeroes) show_digit(digit); digit = 0; if (num <= -800) { num += 800; digit += 8; zeroes = 0; } else if (num <= -400) { num += 400; digit += 4; zeroes = 0; } if (num <= -200) { num += 200; digit += 2; zeroes = 0; } if (num <= -100) { num += 100; digit += 1; zeroes = 0; } if (!zeroes) show_digit(digit); digit = 0; if (num <= -80) { num += 80; digit += 8; zeroes = 0; } else if (num <= -40) { num += 40; digit += 4; zeroes = 0; } if (num <= -20) { num += 20; digit += 2; zeroes = 0; } if (num <= -10) { num += 10; digit += 1; zeroes = 0; } if (!zeroes) show_digit(digit); show_digit((int8_t)-num); *dest++ = ' '; *dest = 0x80; } static volatile int8_t counter = 0; static volatile int8_t counterDummy = 0; unsigned int8_t mouse_x, mouse_y; int8_t mouse_down, mouse_was_down; volatile unsigned int8_t *rand = (volatile unsigned int *) 0xc87b; volatile unsigned int8_t *timer_lo = (volatile unsigned int *) 0xD004; __attribute__ ((interrupt)) static void gameLoop (void) { static int entered = 0; if ((dp_VIA_int_flags & 0x20) == 0) return; // for anything except the t2 timer we want to rti immediately. if (entered) return; // just in case drawing takes longer than one frame entered += 1; iWaitRecal (); *(volatile int8_t *) 0xC81A = 0; // maximum analog resolution Joy_Analog (); mouse_x = (uint8_t) (((long) Vec_Joy_1_X + 128L)); // -128:127 maps to 0:255 mouse_y = (uint8_t) (((long) Vec_Joy_1_Y + 128L)); // but scaled down to preserve margins Reset0Ref (); set_scale (DRAWING_SCALE); Intensity_7F (); intFrameNo += 1L; // DRAW STUFF HERE // int routine draws solid border, main code draws dotted... drawline(-128,-128,-128,127,1,0); // swap p1 p2 to use 2 segments instead of 3 drawline(-128, 127, 127,127,1,0); drawline( 127,-128, 127, 127, 1,0); drawline(-128,-128, 127,-128,1,0); { static unsigned int i; // draw precomputed object - includes dotted frame, which is only partial // if the 'drawships' call has not returned. for (i = 0; i < next_point; i++) { drawline(FromX[i],FromY[i], ToX[i],ToY[i], 0, 1); } } Read_Btns (); mouse_down = ((Vec_Btn_State & 8) != 0); Reset0Ref (); set_scale (DRAWING_SCALE); Intensity_7F (); last_intensity = -128; if (mouse_down && !mouse_was_down) { // this was a click } else if (mouse_down) { // this is a continuing drag } else if (mouse_was_down) { // (but is no longer...) // end of drag - drop now. } else { // no change, just redraw } mouse_was_down = mouse_down; { static char num[9]; // 5 digits, minus, space, 0x80, 0x0 // show the strength of the computer's position... Intensity_7F(); SHOW_NUM(num, intFrameNo); Print_Str_d(-128,-32, num); SHOW_NUM(num, fgFrameNo); Print_Str_d(-112,-32, num); SHOW_NUM(num, next_point); Print_Str_d(-112,-64, num); SHOW_NUM(num, DebugValue); Print_Str_d(-112,64, num); SHOW_NUM(num, (long)Vec_Loop_Count); Print_Str_d(-128,64, num); SHOW_NUM(num, (long)entered); Print_Str_d(-128,-64, num); } // DRAW MORE STUFF HERE? dotmask = (dotmask << 1) | (dotmask >> 7); entered -= 1; // release lock } #define IRQBASE 0xCBF8 // this must be IRQ not FIRQ! uint16_t volatile *const IRQ = (uint16_t *) (IRQBASE + 1); uint8_t volatile *const IRQ_INST = (uint8_t *) IRQBASE; #define WAIT_VALUE 15 void start_graphics_thread (void (*gameLoop) (void)) { *IRQ_INST = (unsigned int) 0x7e; // JMP ... this is actually code!, // first a JMP instruction *IRQ = (unsigned long) gameLoop; // to Address #define LITTLE_ENDIAN(a) ( (((a)>>8L)&255L) | (((a)&255L)<<8L) ) //Vec_Rfrsh = (unsigned long int) (LITTLE_ENDIAN (62000UL)); // 0 //Vec_Rfrsh = (unsigned long int) (LITTLE_ENDIAN (62500UL)); // 1 //Vec_Rfrsh = (unsigned long int) (LITTLE_ENDIAN (62700UL)); // 5 //Vec_Rfrsh = (unsigned long int) (LITTLE_ENDIAN (62900UL)); // 10 Vec_Rfrsh = (unsigned long int) (LITTLE_ENDIAN (64000UL)); // 478 // longer period, more iterations before failing // during one run, the fgFrameNo count slows down until it eventually stops // conclusion: some lossage - maybe heap is growing once every few interrupts? // ensure timer is sensible to start with dp_VIA_t2 = Vec_Rfrsh; // in RAM the BIOS default value of T2 = // 30000 cycles // enable T2 interrupt generation in VIA dp_VIA_int_enable |= 0x20; ENABLE_IRQ_6809; } int main (void) { int done = 0; unsigned int xangle=0;; // unfortunately, on emulator at least, very first random is always the // same // maybe ask Malban to add some randomicity to initial hardware timer? initRandom (rand[0], rand[1], rand[2], *timer_lo); Vec_Joy_Mux_1_X = 1; // enable analog joystick mode Vec_Joy_Mux_1_Y = 3; mouse_was_down = FALSE; mouse_down = FALSE; start_graphics_thread (gameLoop); for (;;) { // Computation thread: if (1 || done == 0) { //done = 1; // only generate the drawing once... // Current (broken) implementation is taking about 70 frames to compute! // bottom and right next_point = 0; FromX[next_point]=-1280; FromY[next_point]=-1280; ToX[next_point]=-1280; ToY[next_point]=1270; next_point += 1; FromX[next_point]=-1280; FromY[next_point]=1270; ToX[next_point]=1270; ToY[next_point]=1270; next_point += 1; if (0) DrawShip(2, // fewest vectors = 30 ... 0,0,256, // x y z 32, 0, 0, // xangle, yangle, zangle, 0, 0, // screenx, screeny, 1, 1 // PreMul, PreDiv ); xangle += 1; DebugValue=2000; // top and left FromX[next_point]=1270; FromY[next_point]=-1280; ToX[next_point]=1270; ToY[next_point]=1270; next_point += 1; // drawing the box before and after the contents will help FromX[next_point]=1270; FromY[next_point]=-1280; ToX[next_point]=-1280; ToY[next_point]=-1280; next_point += 1; } DebugValue=4000; DebugValue=5000; DebugValue=6000; //fgFrameNo += 100L; asm ("CWAI #0xef"); // by waiting for interrupt to happen fgFrameNo += 1L; DebugValue=7000; } DebugValue=3000; // fgFrameNo += 1L; // going from 0 to 1 confirms DrawShip has returned return 0; (void) drawline; (void) mystrdup; (void) mystrchr; (void) atoui; (void) random8; }