static char *rcsid = "$Header: /plaid/homes/zeus/Blind-2.47/RCS/loadgame.c,v 2.46 1997/04/18 12:06:12 zeus Exp $";

/*
 * $Log: loadgame.c,v $
 * Revision 2.46  1997/04/18 12:06:12  zeus
 * *** empty log message ***
 *
 * Revision 2.45  1996/12/31  23:40:54  zeus
 * Revision 2.44  1995/12/31  19:45:18  zeus
 * Revision 2.43  1995/03/20  01:43:09  zeus
 * Revision 2.42  1994/05/17  13:43:15  bampton
 * Revision 2.41  1994/04/08  03:11:28  bampton
 * Revision 2.40  1994/03/09  20:22:55  bampton
 * Revision 2.38  1993/09/27  17:15:54  bampton
 */

#define NOTIMEB
#include "protos/common.h"
#include "protos/prototypes.h"
#include "protos/i-o.h"
#include "protos/misc-g.h"
#include "protos/exit.h"

void loadgame_rcsid (void);
player *players;
planet *planets;
sorted *sorted_planets;
shiptype *shiptypes;
battle *battles;
bombing *bombings;
double galaxysize;
char buf[MAXSTRLEN], buf2[MAXSTRLEN];
int file;
int turn;
int turn_run = 0;
int randseed;
planetdefense *defender;
tmppname *tmpname;
extern int nplanets;

fleetname *fleets;

#ifdef GAMENAME
extern char gamename[MAXTEXT];

#endif

#if SPEED&2
#define NUMTOP numtop2
#else
#define NUMTOP numtop
#endif

void
loadgame_rcsid (void)
{
  printf ("%s\n", rcsid);
}

#if SPEED&1
void
Read (void *p, int n)
{
  int r;
  static struct stat *fileinfo;
  static void *Fptr, *Fptr2;
  static unsigned bytesread = 0;

  if (fileinfo == NULL)
  {
    fileinfo = alloc (sizeof (struct stat));

    (void) stat ("blindrc", fileinfo);
    Fptr = alloc ((unsigned) fileinfo->st_size);
    if ((r = read (file, Fptr, fileinfo->st_size)) != fileinfo->st_size)
    {
      printf ("Can't read %d bytes from file, returncode = %d.\n", n, r);
      exit (LBADBLINDRC);
    }
    Fptr2 = Fptr;
  }
  memcpy (p, Fptr2, (unsigned) n);
  Fptr2 += n;
  bytesread += n;
  if (bytesread >= fileinfo->st_size)
  {
    free (Fptr);
    free (fileinfo);
  }
}
#else

void
Read (void *p, int n)
{
  int r;

  if ((r = read (file, p, READT n)) != n)
  {
    printf ("Can't read %d bytes from file, returncode = %d.\n", n, r);
    exit (LBADBLINDRC);
  }
}
#endif

void
readlist (void *base, int size)
{
  int n;
  list **p = base;

  Read (&n, (int) sizeof (n));
  /*  printf ("Reading %d elements size %d\n",n,size); */
  while (--n >= 0)
  {
    *p = alloc ((unsigned) size);
    Read (*p + 1, size - (int) sizeof (list *));
    p = (list **) (*p);
  }
  *p = 0;
}

int
readint (void)
{
  int i;

  Read (&i, (int) sizeof (i));
  return i;
}

void
loadgame (void)
{
  int i;
  planet *p;
  player *P;
  group *g;
  shiptype *T;
  alliance *a;
  defensive *d;                 /* def mod */
  battle *B;
  shot *S;
  viewer *V;
  participant *PA;
  bombing *b;
  fleetname *f;
  techinfo *t;

#ifdef KCMD
  planetdefense *df;

#endif

#ifdef VERBOSE
  printf ("Reading game from file blindrc...");
#endif

#ifdef GAMENAME
  Read (&gamename, (int) sizeof (gamename));
#endif

  Read (&galaxysize, (int) sizeof (galaxysize));
  Read (&turn, (int) sizeof (turn));
  Read (&randseed, (int) sizeof (randseed));

#if HPUX9 || SOLARIS || USESRAND48
  srand48 ((long) randseed);
#else
  srandom (SRANDTYPE randseed);
#endif

  readlist (&planets, (int) sizeof (planet));
  nplanets = 0;
  for (p = planets; p; p = p->next)
  {
    nplanets++;
  }

#if SPEED&2
  (void) numtop2 (planets, -1);
#endif

#ifdef SIZEBUG
  readlist (&shiptypes, (int) sizeof (shiptype) + (int) sizeof (int));

#else
  readlist (&shiptypes, sizeof (shiptype));
#endif

  readlist (&players, (int) sizeof (player));
  readlist (&sorted_planets, (int) sizeof (sorted)); /* sorted reporting list */
  sortplanets ();               /* re-sort, just to be safe */

#ifdef KCMD
  {
    int n, ndf;

    n = readint ();
    for (ndf = 0; ndf < n; ndf++)
    {
      df = (planetdefense *) alloc ((int) sizeof (planetdefense));
      df->dipstat = readint ();
      df->defender = NUMTOP (players, readint ());
      df->planet = NUMTOP (planets, readint ());
      addlist (&defender, df);
    }
  }
#else

  readlist (&defender, sizeof (planetdefense));
#endif

  for (P = players; P; P = P->next)
  {
    readlist (&P->allies, (int) sizeof (alliance));
    /* def mod */
    readlist (&P->defend, (int) sizeof (defensive));
    readlist (&P->groups, (int) sizeof (group));
    P->x = readint ();
    P->y = readint ();
    P->size = readint ();
  }
  for (p = planets; p; p = p->next)
  {
    p->owner = NUMTOP (players, readint ());
    p->producingshiptype = NUMTOP (shiptypes, readint ());
    for (i = 0; i < MAXCARGO; i++)
      p->routes[i] = NUMTOP (planets, readint ());
  }
  for (T = shiptypes; T; T = T->next)
  {
    T->owner = NUMTOP (players, readint ());
    assert (T->owner != NULL);
  }
  for (P = players; P; P = P->next)
  {
    for (a = P->allies; a; a = a->next)
    {
      a->ally = NUMTOP (players, readint ());
      assert (a->ally != NULL);
    }
    /* def mod */
    for (d = P->defend; d; d = d->next)
    {
      d->defend = NUMTOP (players, readint ());
      assert (d->defend != NULL);
    }
    for (g = P->groups; g; g = g->next)
    {
      g->type = NUMTOP (shiptypes, readint ());
      assert (g->type != NULL);
      g->from = NUMTOP (planets, readint ());
      assert (g->from != NULL);
      g->where = NUMTOP (planets, readint ());
      assert (g->where != NULL);
    }
  }
  readlist (&battles, (int) sizeof (battle));
  for (B = battles; B; B = B->next)
  {
    readlist (&B->shots, (int) sizeof (shot));
    for (S = B->shots; S; S = S->next)
    {
      S->attacker = NUMTOP (shiptypes, readint ());
      assert (S->attacker != NULL);
      S->target = NUMTOP (shiptypes, readint ());
      assert (S->target != NULL);
    }
    readlist (&B->viewers, (int) sizeof (viewer));
    for (V = B->viewers; V; V = V->next)
    {
      V->who = NUMTOP (players, readint ());
      assert (V->who != NULL);
    }
    readlist (&B->participants, (int) sizeof (participant));
    for (PA = B->participants; PA; PA = PA->next)
    {
      PA->who = NUMTOP (players, readint ());
      assert (PA->who != NULL);
      readlist (&PA->groups, (int) sizeof (group));
      for (g = PA->groups; g; g = g->next)
      {
        g->type = NUMTOP (shiptypes, readint ());
        assert (g->type != NULL);
        g->from = NUMTOP (planets, readint ());
        assert (g->from != NULL);
        g->where = NUMTOP (planets, readint ());
        assert (g->where != NULL);
      }
    }
    B->where = NUMTOP (planets, readint ());
    assert (B->where != NULL);
  }
  readlist (&bombings, (int) sizeof (bombing));
  for (b = bombings; b; b = b->next)
  {
    readlist (&b->viewers, (int) sizeof (viewer));
    for (V = b->viewers; V; V = V->next)
    {
      V->who = NUMTOP (players, readint ());
      assert (V->who != NULL);
    }
    b->who = NUMTOP (players, readint ());
    assert (b->who != NULL);
    b->where = NUMTOP (planets, readint ());
    assert (b->where != NULL);
    b->whoose = NUMTOP (players, readint ());
    assert (b->whoose != NULL);
  }

  for (P = players; P; P = P->next)
  {
    readlist (&P->othertechs, (int) sizeof (techinfo));
  }
  for (P = players; P; P = P->next)
  {
    for (t = P->othertechs; t; t = t->next)
      t->whoose = NUMTOP (players, readint ());
  }
  readlist (&tmpname, (int) sizeof (tmppname));
  readlist (&fleets, (int) sizeof (fleetname));
  for (f = fleets; f; f = f->next)
  {
    f->owner = NUMTOP (players, readint ());
  }
  /* This is here, becuase I goofed when I wrote the bloody savegame
     stuff the first time around */
  if (fleets)
    for (P = players; P; P = P->next)
    {
      for (g = P->groups; g; g = g->next)
        g->fleet = numtofleet (readint ());
    }
  else                          /* Sanity check, more than anything... */
    for (P = players; P; P = P->next)
    {
      for (g = P->groups; g; g = g->next)
        g->fleet = NULL;
    }

  close (file);
}

int
opengame (void)
{
  file = open ("blindrc", O_RDONLY | O_BINARY);
  return (file);
}
