/* * Example program for the Allegro library, by Dave Thomson. * * This program draws a 3D starfield (depth-cued) and a polygon * starship (controllable with the keyboard cursor keys), using * the Allegro math functions. */ #include /* starfield system */ typedef struct VECTOR { fixed x, y, z; } VECTOR; #define NUM_STARS 512 #define Z_NEAR 24 #define Z_FAR 1024 #define XY_CUBE 2048 #define SPEED_LIMIT 20 VECTOR stars[NUM_STARS]; fixed star_x[NUM_STARS]; fixed star_y[NUM_STARS]; VECTOR delta; /* polygonal models */ #define NUM_VERTS 4 #define NUM_FACES 4 #define ENGINE 3 /* which face is the engine */ #define ENGINE_ON 64 /* colour index */ #define ENGINE_OFF 32 typedef struct FACE /* for triangular models */ { int v1, v2, v3; int colour, range; VECTOR normal, rnormal; } FACE; typedef struct MODEL { VECTOR points[NUM_VERTS]; FACE faces[NUM_FACES]; fixed x, y, z; fixed rx, ry, rz; int minx, miny, maxx, maxy; VECTOR aim; int velocity; } MODEL; MODEL ship; VECTOR direction; BITMAP *buffer; /* initialises the starfield system */ void init_stars(void) { int i; for (i=0; i> 1)); stars[i].y = itofix((AL_RAND() % XY_CUBE) - (XY_CUBE >> 1)); stars[i].z = itofix((AL_RAND() % (Z_FAR - Z_NEAR)) + Z_NEAR); } delta.x = 0; delta.y = 0; delta.z = 0; } /* draws the starfield */ void draw_stars(void) { int i, c; MATRIX m; VECTOR outs[NUM_STARS]; for (i=0; i> 8) + 16; putpixel(buffer, fixtoi(star_x[i]), fixtoi(star_y[i]), palette_color[c]); } } /* deletes the stars from the screen */ void erase_stars(void) { int i; for (i=0; i itofix(XY_CUBE >> 1)) stars[i].x = itofix(-(XY_CUBE >> 1)); else if (stars[i].x < itofix(-(XY_CUBE >> 1))) stars[i].x = itofix(XY_CUBE >> 1); if (stars[i].y > itofix(XY_CUBE >> 1)) stars[i].y = itofix(-(XY_CUBE >> 1)); else if (stars[i].y < itofix(-(XY_CUBE >> 1))) stars[i].y = itofix(XY_CUBE >> 1); if (stars[i].z > itofix(Z_FAR)) stars[i].z = itofix(Z_NEAR); else if (stars[i].z < itofix(Z_NEAR)) stars[i].z = itofix(Z_FAR); } } /* initialises the ship model */ void init_ship(void) { VECTOR v1, v2, *pts; FACE *face; int i; ship.points[0].x = itofix(0); ship.points[0].y = itofix(0); ship.points[0].z = itofix(32); ship.points[1].x = itofix(16); ship.points[1].y = itofix(-16); ship.points[1].z = itofix(-32); ship.points[2].x = itofix(-16); ship.points[2].y = itofix(-16); ship.points[2].z = itofix(-32); ship.points[3].x = itofix(0); ship.points[3].y = itofix(16); ship.points[3].z = itofix(-32); ship.faces[0].v1 = 3; ship.faces[0].v2 = 0; ship.faces[0].v3 = 1; pts = &ship.points[0]; face = &ship.faces[0]; v1.x = (pts[face->v2].x - pts[face->v1].x); v1.y = (pts[face->v2].y - pts[face->v1].y); v1.z = (pts[face->v2].z - pts[face->v1].z); v2.x = (pts[face->v3].x - pts[face->v1].x); v2.y = (pts[face->v3].y - pts[face->v1].y); v2.z = (pts[face->v3].z - pts[face->v1].z); cross_product(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, &(face->normal.x), &(face->normal.y), &(face->normal.z)); ship.faces[1].v1 = 2; ship.faces[1].v2 = 0; ship.faces[1].v3 = 3; face = &ship.faces[1]; v1.x = (pts[face->v2].x - pts[face->v1].x); v1.y = (pts[face->v2].y - pts[face->v1].y); v1.z = (pts[face->v2].z - pts[face->v1].z); v2.x = (pts[face->v3].x - pts[face->v1].x); v2.y = (pts[face->v3].y - pts[face->v1].y); v2.z = (pts[face->v3].z - pts[face->v1].z); cross_product(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, &(face->normal.x), &(face->normal.y), &(face->normal.z)); ship.faces[2].v1 = 1; ship.faces[2].v2 = 0; ship.faces[2].v3 = 2; face = &ship.faces[2]; v1.x = (pts[face->v2].x - pts[face->v1].x); v1.y = (pts[face->v2].y - pts[face->v1].y); v1.z = (pts[face->v2].z - pts[face->v1].z); v2.x = (pts[face->v3].x - pts[face->v1].x); v2.y = (pts[face->v3].y - pts[face->v1].y); v2.z = (pts[face->v3].z - pts[face->v1].z); cross_product(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, &(face->normal.x), &(face->normal.y), &(face->normal.z)); ship.faces[3].v1 = 2; ship.faces[3].v2 = 3; ship.faces[3].v3 = 1; face = &ship.faces[3]; v1.x = (pts[face->v2].x - pts[face->v1].x); v1.y = (pts[face->v2].y - pts[face->v1].y); v1.z = (pts[face->v2].z - pts[face->v1].z); v2.x = (pts[face->v3].x - pts[face->v1].x); v2.y = (pts[face->v3].y - pts[face->v1].y); v2.z = (pts[face->v3].z - pts[face->v1].z); cross_product(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, &(face->normal.x), &(face->normal.y), &(face->normal.z)); for (i=0; i ship.maxx) ship.maxx = fixtoi(outs[i].x); if (fixtoi(outs[i].y) < ship.miny) ship.miny = fixtoi(outs[i].y); if (fixtoi(outs[i].y) > ship.maxy) ship.maxy = fixtoi(outs[i].y); } for (i=0; i 0) ship.velocity -= 2; } ship.rx &= itofix(255); ship.ry &= itofix(255); ship.rz &= itofix(255); delta.x = fixmul(direction.x, itofix(ship.velocity)); delta.y = fixmul(direction.y, itofix(ship.velocity)); delta.z = fixmul(direction.z, itofix(ship.velocity)); } destroy_bitmap(buffer); return 0; } END_OF_MAIN()