Logo Search packages:      
Sourcecode: acm4 version File versions  Download package

init.c

/*
 *  acm : an aerial combat simulator for X
 *  Copyright (C) 1991-1994  Riley Rainey
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 dated June, 1991.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program;  if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
 */

#include <X11/Xos.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "pm.h"
#include "alarm.h"

extern craftType *newCraft();
extern craftType *lookupCraft();
extern int  compileAircraftInventory();
extern void initaim9(), initm61a1();
extern void buildExplosion();
extern void placeObject();
extern void InitNavaidSystem();
extern void DMECheckAlarm();
extern void resupplyCheck();
extern void acm_srand PARAMS((int seed));

/*
 *  Defined in doViews.c :
 */

extern VPolygon **poly;
extern long polyCount;

void undersampleObject();

static char *errmsg = "Sorry, I cannot find the file %s in ../objects/ or %s\n";

/*
 *  acm_fopen :  Open an important acm data file (or die trying).
 */

FILE *
acm_fopen (name, access)
char *name, *access;
{

      FILE  *f;
      char  libname[256];

      if ((f = fopen (name, access)) == (FILE *) NULL) {
            strcpy (libname, "../objects/");
            strcat (libname, name);
            if ((f = fopen (libname, access)) == (FILE *) NULL) {
                  strcpy (libname, ACM_LIBRARY);
                  strcat (libname, name);
                  if ((f = fopen (libname, access)) == (FILE *) NULL) {
                        fprintf (stderr, errmsg, name, ACM_LIBRARY);
                        exit (1);
                  }
            }
      }

      return f;
}

/*
 *  acm_find_file :  Find an important acm data file (or die trying).
 */

char *
acm_find_file (name)
char *name;
{
      static char pname[1024];
      struct stat statbuf;

      strcpy(pname, name);
      if (stat (name, &statbuf) != 0) {
            strcpy (pname, "../objects/");
            strcat (pname, name);
            if (stat (pname, &statbuf) != 0) {
                  strcpy (pname, ACM_LIBRARY);
                  strcat (pname, name);
                  if (stat (pname, &statbuf) != 0) {
                        fprintf (stderr, errmsg, name, ACM_LIBRARY);
                        exit (1);
                  }
            }
      }

      return pname;
}


/*
 *  readScene :  Process the scene description file, returns zero if successful
 *           or -1 otherwise.
 */

int
readScene(ground, len)
char  *ground;
int   len;
{
      FILE  *f, *f1;
      char  file[256], *name, *filep;
      double      x, y, z, heading;
      int   s, i = 0, undersample, depthcue;
      craftType * c;
      extern      char *sceneFile;  /* from server.c */

      name = (sceneFile) ? sceneFile : "default-scene";

      f = acm_fopen (name, "r");

      fscanf (f, "%lf %lf %lf %lf", &x, &y, &z, &heading);
      teamLoc[1].x = x * NM;
      teamLoc[1].y = y * NM;
      teamLoc[1].z = z * NM;
      teamHeading[1] = DEGtoRAD(heading);

      fscanf (f, "%lf %lf %lf %lf", &x, &y, &z, &heading);
      teamLoc[2].x = x * NM;
      teamLoc[2].y = y * NM;
      teamLoc[2].z = z * NM;
      teamHeading[2] = DEGtoRAD(heading);

/*
 *  Get the ground color (the first call to fgets() gets us to a new line).
 */
      
      ground[0] = '\0';
      if (fgets (ground, len, f) == (char *) NULL) {
            return -1;
      }
      if (fgets (ground, len, f) == (char *) NULL) {
            return -1;
      }
      len = strlen(ground);
      if (len > 0 && ground[len-1] == '\n') {
            ground[len-1] = '\0';
      }

      while (s = fscanf(f, "%s %lf %lf %lf %lf",
            file, &x, &y, &z, &heading) == 5) {

            depthcue = 1;

            if (file[0] == '@') {
                  filep = &file[1];
                  undersample = 1;
            }
            else if (file[0] == '+') {
                  filep = &file[1];
                  depthcue = 0;
            }
            else {
                  filep = file;
                  undersample = 0;
            }
            stbl[i].type = CT_SURFACE;
            if ( c = lookupCraft(filep) ) {
                  stbl[i].cinfo = c;
            }
            else {
                  f1 = acm_fopen (filep, "r");
                  stbl[i].cinfo = newCraft();
                  stbl[i].cinfo->name = strdup(filep);
                  stbl[i].cinfo->object =
                        VReadDepthCueuedObject(f1, depthcue);
                  if (!stbl[i].cinfo->object) {
                        fprintf (stderr,
                              "Error reading object %s\n", filep);
                        exit (1);
                  }
                  if (undersample) {
                        undersampleObject (stbl[i].cinfo->object, 3);
                  }
                  fclose (f1);
            }
            stbl[i].Sg.x = x * NM;
            stbl[i].Sg.y = y * NM;
            stbl[i].Sg.z = z * NM;
            stbl[i].curHeading = DEGtoRAD(heading);
            stbl[i].curPitch = stbl[i].curRoll = 0.0;
            if (++i == MAXSURFACE) {
                  fprintf (stderr,
            "Only the first %d surface objects will be displayed.\n",
                  MAXSURFACE);
                  return 0;
            }
      }
      return (s == EOF || s == 0) ? 0 : -1;
}

/*
 *  undersampleObject
 *
 *  Remove some of the detail in an object to reduce the CPU overhead
 *  of transforming and clipping it.
 */

void
undersampleObject (obj, rate)
VObject     *obj;
int   rate;
{
      int   i, j, k;

      k = 0;

      for (i=1; i<obj->numPolys; ++i) {
            for (j=0; j<obj->polygon[i]->numVtces; j+=rate) {
                  obj->polygon[i]->vertex[k++] =
                        obj->polygon[i]->vertex[j];
            }
            obj->polygon[i]->numVtces = k;
      }
}

/*
 *  init :  Set up the acm server
 */

int
init ()
{
      int   i;
      craft *p;
      alarm_id_t id;
      char  ground[256];

      polyCount = 32768;
      poly = (VPolygon **) Vmalloc (sizeof(VPolygon *) * polyCount);

      cbase = - 2800.0;
      ctop  = - 9000.0;

/*
 *  VSetDepthCue() must be called before calling VSetVisibility().
 */

      VSetDepthCue (VAllocColor("#749395"), 8);
      VSetVisibility (visibility);


        for ((i=0, p=stbl); i<MAXSURFACE; (++i, ++p))
            p->type = CT_FREE;

        for ((i=0, p=ptbl); i<MAXPLAYERS; (++i, ++p)) {
            p->pIndex = i;
            p->type = CT_FREE;
      }

        for ((i=0, p=mtbl); i<MAXPROJECTILES; (++i, ++p))
            p->type = CT_FREE;

      acm_srand ( (int) time(0) );

      HUDColor = VAllocColor ("white");
      whiteColor = VAllocColor ("white");
      blackColor = VAllocColor ("black");
      radarColor = VAllocColor ("#0c0");
      radarBackgroundColor = VAllocColor ("#094200");
      cloudColor = VAllocDepthCueuedColor ("#ccc", 1);

      buildExplosion();

/*
 *  Set up the scene
 */

      if (readScene (ground, sizeof(ground)) != 0) {
            fprintf (stderr, "Fatal error\n");
            exit (1);
      }

      groundColor = VAllocDepthCueuedColor (ground, 1);

/*
 *  Compile the aircraft inventory
 */

      if (compileAircraftInventory() != 0) {
            fprintf (stderr, "Fatal error\n");
            exit (1);
      }

/*
 *  Initialize weapons
 */

      initaim9();
      initm61a1();

/*
 *  Set up the navaids.
 */

      InitNavaidSystem ();
      id = addAlarm (5.0, DMECheckAlarm, NULL, NULL);

/*
 *  Add the periodic resupply check procedure
 */

      id = addAlarm (RESUPPLY_INTERVAL, resupplyCheck, NULL, NULL);

/*
 *  Set time intervals.
 */

      deltaT = (double) UPDATE_INTERVAL / 1000000.0;

      halfDeltaTSquared = 0.5 * deltaT * deltaT;

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index