static char *rcsid = "$Header: /plaid/homes/zeus/Blind-2.47/RCS/savegame.c,v 2.47 1998/04/15 21:29:39 zeus Exp zeus $";

/*
 * $Log: savegame.c,v $
 * Revision 2.47  1998/04/15 21:29:39  zeus
 * *** empty log message ***
 *
 * 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.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.39  1993/10/28  22:31:20  bampton
 * Revision 2.38  1993/09/27  17:15:54  bampton
 * Revision 2.37  1993/09/07  20:50:32  bampton
 *
 */

#ifdef OSF1
#define NOTIMEB
#else
#include <time.h>
#endif

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

void savegame_rcsid (void);
extern player *players;
extern planet *planets;
extern sorted *sorted_planets;
extern shiptype *shiptypes;
extern battle *battles;
extern bombing *bombings;
extern double galaxysize;
extern char buf[256], buf2[256];
extern int file;
extern int turn;
extern int turn_run;
extern int randseed;
extern planetdefense *defender;
extern tmppname *tmpname;
extern fleetname *fleets;

#ifdef GAMENAME
extern char gamename[MAXTEXT];

#endif

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


int
listlen (void *base)
{
  list *p;
  int i = 0;

  for (p = base; p; p = p->next, i++);
  return i;
}

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

  if ((r = write (file, p, WRITET n)) != n)
  {
    printf ("Can't write %d bytes to file, returncode = %d.\n", n, r);
    exit (SBADBLINDRC);
  }
}

#ifndef PREPROC
void
writeint (int i)
{
  Write (&i, sizeof (i));
}

void
writelist (void *base, int size)
{
  list *p;

/* printf ("Writing %d items of %d bytes\n",(listlen ((list *) base)),size); */
  size -= sizeof (list *);
  writeint (listlen ((list *) base));
  for (p = base; p; p = p->next)
    Write (p + 1, size);
}

void
writelist2 (void *base, int size, int size2)
{
  list *p;
  char j = 0;
  int k;

/*  printf ("Writing %d items and adding %d bytes to %d\n",(listlen ((list *) base)),size2,size); */
  size -= sizeof (list *);
  writeint (listlen ((list *) base));
  for (p = base; p; p = p->next)
  {
    Write (p + 1, size);
    for (k = 0; k < size2; k++)
    {
      Write (&j, 1);
    }
  }
}

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

#ifdef KCMD
  planetdefense *df;

#endif

  file = open ("blindrc", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600);
  if (file < 0)
  {
    printf ("Can't create file blindrc.\n");
    exit (SBADBLINDRC);
  }

  printf ("Writing game to file blindrc...\n");

#ifdef GAMENAME
  Write (&gamename, sizeof (gamename));
#endif

  Write (&galaxysize, sizeof (galaxysize));
  writeint (turn);

  /* Save new random seed, if a turn has been run */
  if (turn_run)
    writeint ((int) (time (NULL)));
    /*writeint ((int) ((time (NULL)) % 32768));*/
  else
    writeint (randseed);
  writelist (planets, sizeof (planet));

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

#else
  writelist (shiptypes, sizeof (shiptype));
#endif

  writelist (players, sizeof (player));
  writelist (sorted_planets, sizeof (sorted));  /* sorted planet list */


#ifdef KCMD
  writeint (listlen ((void *) defender));
  for (df = defender; df; df = df->next)
  {
    writeint (df->dipstat);
    writeint (ptonum (players, df->defender));
    writeint (ptonum (planets, df->planet));
  }
#else

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

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

  for (P = players; P; P = P->next)
  {
    writelist (P->othertechs, sizeof (techinfo));
  }
  for (P = players; P; P = P->next)
  {
    for (t = P->othertechs; t; t = t->next)
      writeint (ptonum (players, t->whoose));
  }
  writelist (tmpname, sizeof (tmppname));
  writelist (fleets, sizeof (fleetname));
  for (f = fleets; f; f = f->next)
  {
    writeint (ptonum (players, f->owner));
  }
  if (fleets)
    for (P = players; P; P = P->next)
    {
      for (g = P->groups; g; g = g->next)
        writeint (fleettonum (g));
    }
  close (file);
}
#endif
