Code Search for Developers
 
 
  

exstars.c from Allegro game programming library at Krugle


Show exstars.c syntax highlighted

/*
 *    Example program for the Allegro library, by Dave Thomson.
 *
 *    This program draws a 3D starfield (depth-cued) and a al_draw_polygon
 *    starship (controllable), using the Allegro math functions.
 */


#include <stdio.h>

#include "allegro.h"



/* 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;


AL_BITMAP *buffer;



/* initialises the starfield system */
void init_stars(void)
{
   int i;

   for (i=0; i<NUM_STARS; i++) {
      stars[i].x = al_int_to_fix((rand() % XY_CUBE) - (XY_CUBE >> 1));
      stars[i].y = al_int_to_fix((rand() % XY_CUBE) - (XY_CUBE >> 1));
      stars[i].z = al_int_to_fix((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;
   AL_MATRIX m;
   VECTOR outs[NUM_STARS];

   for (i=0; i<NUM_STARS; i++) {
      al_get_translation_matrix(&m, delta.x, delta.y, delta.z);
      al_apply_matrix(&m, stars[i].x, stars[i].y, stars[i].z, &outs[i].x, &outs[i].y, &outs[i].z);
      al_persp_project(outs[i].x, outs[i].y, outs[i].z, &star_x[i], &star_y[i]);
      c = (al_fix_to_int(outs[i].z) >> 8) + 16;
      al_put_pixel(buffer, al_fix_to_int(star_x[i]), al_fix_to_int(star_y[i]), al_palette_color[c]);
   }
}



/* deletes the stars from the al_screen */
void erase_stars(void)
{
   int i;

   for (i=0; i<NUM_STARS; i++)
      al_put_pixel(buffer, al_fix_to_int(star_x[i]), al_fix_to_int(star_y[i]), al_palette_color[0]);
}



/* moves the stars */
void move_stars(void)
{
   int i;

   for (i=0; i<NUM_STARS; i++) {
      stars[i].x += delta.x;
      stars[i].y += delta.y;
      stars[i].z += delta.z;

      if (stars[i].x > al_int_to_fix(XY_CUBE >> 1))
	 stars[i].x = al_int_to_fix(-(XY_CUBE >> 1));
      else if (stars[i].x < al_int_to_fix(-(XY_CUBE >> 1)))
	 stars[i].x = al_int_to_fix(XY_CUBE >> 1);

      if (stars[i].y > al_int_to_fix(XY_CUBE >> 1))
	 stars[i].y = al_int_to_fix(-(XY_CUBE >> 1));
      else if (stars[i].y < al_int_to_fix(-(XY_CUBE >> 1)))
	 stars[i].y = al_int_to_fix(XY_CUBE >> 1);

      if (stars[i].z > al_int_to_fix(Z_FAR))
	 stars[i].z = al_int_to_fix(Z_NEAR);
      else if (stars[i].z < al_int_to_fix(Z_NEAR))
	 stars[i].z = al_int_to_fix(Z_FAR);
   }
}



/* initialises the ship model */
void init_ship(void)
{
   VECTOR v1, v2, *pts;
   FACE *face;
   int i;

   ship.points[0].x = al_int_to_fix(0);
   ship.points[0].y = al_int_to_fix(0);
   ship.points[0].z = al_int_to_fix(32);

   ship.points[1].x = al_int_to_fix(16);
   ship.points[1].y = al_int_to_fix(-16);
   ship.points[1].z = al_int_to_fix(-32);

   ship.points[2].x = al_int_to_fix(-16);
   ship.points[2].y = al_int_to_fix(-16);
   ship.points[2].z = al_int_to_fix(-32);

   ship.points[3].x = al_int_to_fix(0);
   ship.points[3].y = al_int_to_fix(16);
   ship.points[3].z = al_int_to_fix(-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);
   al_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);
   al_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);
   al_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);
   al_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<NUM_FACES; i++) {
      ship.faces[i].colour = 32;
      ship.faces[i].range = 15;
      al_normalize_vector(&ship.faces[i].normal.x, &ship.faces[i].normal.y, &ship.faces[i].normal.z);
      ship.faces[i].rnormal.x = ship.faces[i].normal.x;
      ship.faces[i].rnormal.y = ship.faces[i].normal.y;
      ship.faces[i].rnormal.z = ship.faces[i].normal.z;
   }

   ship.x = ship.y = 0;
   ship.z = al_int_to_fix(192);
   ship.rx = ship.ry = ship.rz = 0;

   ship.aim.x = direction.x = 0;
   ship.aim.y = direction.y = 0;
   ship.aim.z = direction.z = al_int_to_fix(-1);
   ship.velocity = 0;
}



/* draws the ship model */
void draw_ship(void)
{
   VECTOR outs[NUM_VERTS];
   AL_MATRIX m;
   int i, col;

   ship.minx = AL_SCREEN_W;
   ship.miny = AL_SCREEN_H;
   ship.maxx = ship.maxy = 0;

   al_get_rotation_matrix(&m, ship.rx, ship.ry, ship.rz);
   al_apply_matrix(&m, ship.aim.x, ship.aim.y, ship.aim.z, &outs[0].x, &outs[0].y, &outs[0].z);
   direction.x = outs[0].x;
   direction.y = outs[0].y;
   direction.z = outs[0].z;

   for (i=0; i<NUM_FACES; i++)
      al_apply_matrix(&m, ship.faces[i].normal.x, ship.faces[i].normal.y, ship.faces[i].normal.z, &ship.faces[i].rnormal.x, &ship.faces[i].rnormal.y, &ship.faces[i].rnormal.z);

   al_get_transformation_matrix(&m, al_int_to_fix(1), ship.rx, ship.ry, ship.rz, ship.x, ship.y, ship.z);

   for (i=0; i<NUM_VERTS; i++) {
      al_apply_matrix(&m, ship.points[i].x, ship.points[i].y, ship.points[i].z, &outs[i].x, &outs[i].y, &outs[i].z);
      al_persp_project(outs[i].x, outs[i].y, outs[i].z, &outs[i].x, &outs[i].y);
      if (al_fix_to_int(outs[i].x) < ship.minx)
	 ship.minx = al_fix_to_int(outs[i].x);
      if (al_fix_to_int(outs[i].x) > ship.maxx)
	 ship.maxx = al_fix_to_int(outs[i].x);
      if (al_fix_to_int(outs[i].y) < ship.miny)
	 ship.miny = al_fix_to_int(outs[i].y);
      if (al_fix_to_int(outs[i].y) > ship.maxy)
	 ship.maxy = al_fix_to_int(outs[i].y);
   }

   for (i=0; i<NUM_FACES; i++) {
      if (al_fix_to_(ship.faces[i].rnormal.z) < 0.0) {
	 col = al_fix_to_int(al_fix_mul(dot_product(ship.faces[i].rnormal.x, ship.faces[i].rnormal.y, ship.faces[i].rnormal.z, 0, 0, al_int_to_fix(1)), al_int_to_fix(ship.faces[i].range)));
	 if (col < 0)
	    col = -col + ship.faces[i].colour;
	 else
	    col = col + ship.faces[i].colour;

	 al_draw_triangle(buffer, al_fix_to_int(outs[ship.faces[i].v1].x), al_fix_to_int(outs[ship.faces[i].v1].y),
		  al_fix_to_int(outs[ship.faces[i].v2].x), al_fix_to_int(outs[ship.faces[i].v2].y),
		  al_fix_to_int(outs[ship.faces[i].v3].x), al_fix_to_int(outs[ship.faces[i].v3].y),
		  al_palette_color[col]);
      }
   }
}



/* removes the ship model from the al_screen */
void erase_ship(void)
{
   al_draw_rect_fill(buffer, ship.minx, ship.miny, ship.maxx, ship.maxy, al_palette_color[0]);
}



int main(int argc, char *argv[])
{
   AL_PALETTE pal;
   char buf[64];
   int i;

   allegro_init();
   al_install_keyboard();
   al_install_timer();
   if (al_set_gfx_mode(AL_GFX_SAFE, 320, 200, 0, 0) != 0) {
      al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
      al_show_message("Unable to set any graphic mode\n%s\n", al_error);
      return 1;
   }

   for (i=0; i<16; i++)
      pal[i].r = pal[i].g = pal[i].b = 0;

   /* greyscale */
   pal[16].r = pal[16].g = pal[16].b = 63;
   pal[17].r = pal[17].g = pal[17].b = 48;
   pal[18].r = pal[18].g = pal[18].b = 32;
   pal[19].r = pal[19].g = pal[19].b = 16;
   pal[20].r = pal[20].g = pal[20].b = 8;

   /* red range */
   for (i=0; i<16; i++) { 
      pal[i+32].r = 31 + i*2;
      pal[i+32].g = 15;
      pal[i+32].b = 7;
   }

   /* a nice fire orange */
   for (i=64; i<68; i++) {
      pal[i].r = 63; 
      pal[i].g = 17 + (i-64)*3;
      pal[i].b = 0;
   }

   al_set_palette(pal);

   buffer = al_create_bitmap(AL_SCREEN_W, AL_SCREEN_H);
   al_clear_bitmap(buffer);

   al_set_projection_viewport(0, 0, AL_SCREEN_W, AL_SCREEN_H);

   init_stars();
   draw_stars();
   init_ship();
   draw_ship();

   for (;;) {
      erase_stars();
      erase_ship();

      move_stars();
      draw_stars();

      sprintf(buf, "     direction: [%f] [%f] [%f]     ", al_fix_to_(direction.x), al_fix_to_(direction.y), al_fix_to_(direction.z));
      al_put_text_centre(buffer, al_font_8x8, buf, AL_SCREEN_W / 2, AL_SCREEN_H-10, al_palette_color[17]);
      sprintf(buf, "   delta: [%f] [%f] [%f]   ", al_fix_to_(delta.x), al_fix_to_(delta.y), al_fix_to_(delta.z));
      al_put_text_centre(buffer, al_font_8x8, buf, AL_SCREEN_W / 2, AL_SCREEN_H-20, al_palette_color[17]);
      sprintf(buf, "   velocity: %d   ", ship.velocity);
      al_put_text_centre(buffer, al_font_8x8, buf, AL_SCREEN_W / 2, AL_SCREEN_H-30, al_palette_color[17]);

      al_put_text_centre(buffer, al_font_8x8, "Press ESC to exit", AL_SCREEN_W/2, 16, al_palette_color[18]);
      al_put_text_centre(buffer, al_font_8x8, "Press CTRL to fire engine", AL_SCREEN_W/2, 32, al_palette_color[18]);

      draw_ship();

      al_vsync();
      al_blit(buffer, al_screen, 0, 0, 0, 0, AL_SCREEN_W, AL_SCREEN_H);

      al_poll_keyboard();

      /* exit program */
      if (al_key[AL_KEY_ESC]) 
	 break;

      /* rotates */
      if (al_key[AL_KEY_UP]) 
	 ship.rx -= al_int_to_fix(5);
      else if (al_key[AL_KEY_DOWN])
	 ship.rx += al_int_to_fix(5);

      if (al_key[AL_KEY_LEFT])
	 ship.ry -= al_int_to_fix(5);
      else if (al_key[AL_KEY_RIGHT])
	 ship.ry += al_int_to_fix(5);

      if (al_key[AL_KEY_PGUP])
	 ship.rz -= al_int_to_fix(5);
      else if (al_key[AL_KEY_PGDN])
	 ship.rz += al_int_to_fix(5);

      /* thrust */
      if ((al_key[AL_KEY_LCONTROL]) || (al_key[AL_KEY_RCONTROL])) { 
	 ship.faces[ENGINE].colour = ENGINE_ON;
	 ship.faces[ENGINE].range = 3;
	 if (ship.velocity < SPEED_LIMIT)
	    ship.velocity += 2;
      }
      else {
	 ship.faces[ENGINE].colour = ENGINE_OFF;
	 ship.faces[ENGINE].range = 15;
	 if (ship.velocity > 0)
	    ship.velocity -= 2;
      }

      ship.rx &= al_int_to_fix(255);
      ship.ry &= al_int_to_fix(255);
      ship.rz &= al_int_to_fix(255);

      delta.x = al_fix_mul(direction.x, al_int_to_fix(ship.velocity));
      delta.y = al_fix_mul(direction.y, al_int_to_fix(ship.velocity));
      delta.z = al_fix_mul(direction.z, al_int_to_fix(ship.velocity));
   }

   al_destroy_bitmap(buffer);
   return 0;
}

AL_END_OF_MAIN();




See more files for this project here

Allegro game programming library

Allegro is a cross-platform library intended for use in computer games and other types of multimedia programming.

Project homepage: http://sourceforge.net/projects/alleg
Programming language(s): Assembly,C,Shell Script
License: other

  allegro.pcx
  ex12bit.c
  ex3buf.c
  ex3d.c
  exaccel.c
  exalpha.c
  example.dat
  example.h
  examples.txt
  exbitmap.c
  exblend.c
  excamera.c
  excolmap.c
  excustom.c
  exdata.c
  exdbuf.c
  exdodgy.c
  exexedat.c
  exfixed.c
  exflame.c
  exflip.c
  exgui.c
  exhello.c
  exjoy.c
  exkeys.c
  exlights.c
  exmem.c
  exmidi.c
  exmouse.c
  expal.c
  expat.c
  exquat.c
  exrgbhsv.c
  exsample.c
  exscale.c
  exscn3d.c
  exscroll.c
  exshade.c
  exspline.c
  exsprite.c
  exstars.c
  exstream.c
  exswitch.c
  extimer.c
  extrans.c
  extruec.c
  exunicod.c
  exupdate.c
  exxfade.c
  exzbuf.c
  mysha.pcx
  planet.pcx
  running.dat
  running.h
  unifont.dat