static char *rcsid = "$Header: /plaid/homes/zeus/Blind-2.47/util/RCS/ascii-to-blindrc.c,v 2.46 1997/04/18 12:29:49 zeus Exp $";

/* 
   $Log: ascii-to-blindrc.c,v $
   Revision 2.46  1997/04/18 12:29:49  zeus
   *** empty log message ***

   * Revision 2.45  1997/01/01  00:49:33  zeus
   * *** empty log message ***
   *
 */

/*      Galaxy data file ASCII to binary conversion program
   by Russell Wallace 5 February 1992

   following comments actually from bin->ascii program:

   Run the program without any arguments; it will read "blindrc" and write the
   ASCII version to standard output, which should be redirected to a file.
   ASCII version should be slightly smaller than the binary version, however
   some lines may be longer than 80 characters so uuencoding may be required.
   Exact format may depend on version of printf() used; in particular, the
   printf() routine on my C compiler gives exactly 6 decimal places for
   floating-point quantities (implying that any accuracy beyond that will be
   lost in translation), but others may differ.
   ASCII version may be edited, the format is reasonably flexible but it is
   important to ensure that no spaces are introduced anywhere, including at
   the end of lines, and that spaces in strings are not converted to tabs.
   Also, if there are any " symbols in player, ship type or planet names
   within the game, the conversion back to binary will not work - edit by
   hand if necessary - and no number must begin with a decimal point, i.e.
   .435 is no good, it must be written as 0.435.
   Examine galaxy.c or this file for field details if you wish to edit the
   ASCII version, also note that lists of e.g. groups for a player come
   directly after the player record, and that each list is terminated by a
   single . on a line on its own.
   Written in ANSI C, should work on any machine.
   This code is in the public domain.

   Modified Feb 93 by G Ellingson for blind galaxy (Asimov version)
 */


#define NOTIMEB

#include "protos/common.h"
#include "protos/prototypes.h"
#include "protos/a2b.h"



player *players;
planet *planets;
sorted *sorted_planets;         /* NOTE: we do NOT need to output this list; we

                                   can just recreate it in the mkfile.c program,
                                   by calling sortplanets() */
shiptype *shiptypes;
battle *battles;
bombing *bombings;
double galaxysize;
extern int file;
int turn, turn_run;
int nextc;
int randseed;
planetdefense *defender;
fleetname *fleets;
tmppname *tmpname;
char buf[256];

#ifdef GAMENAME
char gamename[MAXTEXT];

#endif

void
Readit (void *p, unsigned int n)
{
  int r;

  if ((r = read (file, p, (int) n)) != (int) n)
  {
    fprintf (stderr, "Can't read %d bytes from file, returncode = %d.\n", n, r);
    exit (1);
  }
}

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

  printf ("a\n");
  Readit (&n, sizeof (n));
  printf (":%d:\n", n);
  while (--n >= 0)
  {
    *p = alloc (size);
    Readit (*p + 1, size - (unsigned int) sizeof (list *));
    p = (list **) (*p);

  }
  *p = (void *) NULL;
}

int
readint (void)
{
  int i;

  Readit (&i, sizeof (i));
  return i;
}

void
cp (void *base, void *target)
{
  list *p;
  int i, n;

  n = (long) (*((void **) target));
  if (!n)
  {
    *((void **) target) = 0;
    return;
  }
  i = 0;
  for (p = base; p; p = p->next)
  {
    i++;
    if (i == n)
    {
      *((void **) target) = p;
      return;
    }
  }
  *((void **) target) = 0;
}

int
gc (void)
{
  int c;

  c = nextc;
  nextc = getchar ();

  /* #definte TEST for early testing only; cannot complete
     correctly if TEST is defined -- Glenn Ellignson */

#ifdef TEST
  if (nextc == EOF)             /* gellings: test for eof */
  {
    printf ("Unexpected EOF.  Aborting.");
    exit (1);
  }
#endif

#ifndef NDEBUG
  putchar (c);
#endif

  return c;
}

void
nl (void)
{
  gc ();

#ifdef MSDOS
  gc ();                        /* LF character.... */
#endif
}

void
gs (char *s)
{
  int i = 0;

  gc ();                        /* open quotes */
  while (nextc != '"')
  {
    *s++ = gc ();
    if (++i == 20)
    {
      printf ("Error in gs()\n");
      exit (1);
    }
  }
  *s = 0;
  gc ();                        /* close quotes */
  gc ();                        /* comma */
  if (nextc == '\n')
    gc ();                      /* newline character */
}

void
gn (char *s)
{

#ifndef NDEBUG
  int i = 0;

#endif

  while (nextc == '-' || nextc == '.' || (nextc >= '0' && nextc <= '9'))

#ifndef NDEBUG
  {
#endif

    *s++ = gc ();

#ifndef NDEBUG
    if (++i == 20)
    {
      printf ("Error in gn()\n");
      exit (1);
    }
  }
#endif

  *s = 0;
  gc ();                        /* comma */
  if (nextc == '\n')
    gc ();                      /* newline character */
}

int
gi (void)
{
  char s[20];

  gn (s);
  return atoi (s);
}

double
gf (void)
{
  char s[20];

  gn (s);
  return atof (s);
}

void
gtech (Tech * t)
{
  t->drive = gf ();
  t->guns = gf ();
  t->shields = gf ();
  t->cargo = gf ();
}


void
galliancelist (alliance ** base)
{
  alliance *a;

  *base = 0;

  while ((nextc != 46))
  {
    a = alloc (sizeof (alliance));
    a->ally = gp ();
    addlist (base, a);
  }
  nl ();
  gc ();
}

void
gdefendlist (defensive ** base)
{
  defensive *a;

  *base = 0;

  while ((nextc != 46))
  {
    a = alloc (sizeof (defensive));
    a->defend = gp ();
    addlist (base, a);
  }
  nl ();
  gc ();
}


void
ggrouplist (group ** base)
{
  group *g;

  *base = 0;
/*      while (!eol) */
  while ((nextc != 46 && nextc != '\n'))
  {
    g = alloc (sizeof (group));
    g->type = gp ();
    gtech (&g->tech);
    g->loadtype = gi ();
    g->load = gf ();
    g->from = gp ();
    g->where = gp ();
    g->dist = gf ();
    g->ships = gi ();
    g->left = gi ();
    g->fleet = gp ();
    addlist (base, g);
  }
  nl ();
  gc ();
}

void
gcarry (techinfo ** t)
{
  techinfo *t2;

  *t = NULL;
/*
   t=alloc (sizeof (techinfo));
   t=gp();
   gtech(t->tech); */
  while ((nextc != 46 && nextc != '\n'))
  {
    t2 = alloc (sizeof (techinfo));
    t2->whoose = gp ();
    gtech (&t2->tech);
    addlist (t, t2);
  }
  nl ();
  gc ();
}

#ifdef KCMD
void
gkcmd (void)
{
  planetdefense *pd, *w;

  defender = alloc (sizeof (planetdefense));
  while ((nextc != 46 && nextc != '\n'))
  {
    pd = alloc (sizeof (planetdefense));
    pd->dipstat = gi ();
    pd->defender = gp ();
    pd->planet = gp ();
    addlist (defender, pd);
  }
  nl ();
  gc ();
  w = defender;
  defender = defender->next;
  free (w);
}
#endif

void
gshotlist (shot ** base)
{
  shot *S;

  *base = 0;
  while (nextc != 46)
  {
    S = alloc (sizeof (shot));
    S->attacker = gp ();
    S->target = gp ();
    S->kill = gi ();
    addlist (base, S);
  }
  nl ();
  gc ();
}

void
gviewerlist (viewer ** base)
{
  viewer *V;

  *base = 0;
  while (nextc != 46)
  {
    V = alloc (sizeof (viewer));
    V->who = gp ();
    addlist (base, V);
  }
  nl ();
  gc ();
}

void
gparticipantlist (participant ** base)
{
  participant *PA;

  *base = 0;
  while (nextc != 46)
  {
    PA = alloc (sizeof (participant));
    printf ("gpart who\n");
    PA->who = gp ();
    printf ("gpart ggroup\n");
    ggrouplist (&PA->groups);
    printf ("gpart addlist\n");
    addlist (base, PA);
    printf ("end gpart addlist\n");
  }
  nl ();
  gc ();
}


void
inputgame (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;
  techinfo *t;
  fleetname *f;

  nextc = getchar ();

#ifdef GAMENAME
  gs (gamename);
#endif

  printf ("Size: ");
  galaxysize = gf ();

  printf ("Turn: ");
  turn = gi ();

  printf ("Seed: ");
  randseed = gi ();

  fprintf (stderr, "Reading Planets\n");
  while (!eol)
  {
    p = alloc (sizeof (planet));
    gs (p->name);
    gs (p->num);

#ifdef VERBOSE
    fprintf (stderr, "Planet name/num %s %s\n", p->name, p->num);
#endif

    p->owner = gp ();
    p->x = gf ();
    assert (p->x > 0.0);
    assert (p->x < galaxysize);
    p->y = gf ();
    assert (p->y > 0.0);
    assert (p->y < galaxysize);
    p->size = gf ();
    assert (p->size >= 0.0);
    p->resources = gf ();
    assert (p->resources >= 0.0);
    assert (p->resources <= 10.0);
    p->pop = gf ();
    p->ind = gf ();
    p->producing = gf ();
    p->producingshiptype = gp ();
    p->col = gf ();
    p->cap = gf ();
    p->mat = gf ();
    p->inprogress = gf ();
    p->spent = gf ();
    for (i = 0; i != MAXCARGO; i++)
      p->routes[i] = gp ();
    p->drive = gf ();
    p->guns = gf ();
    p->shields = gf ();
    p->cargo = gf ();
    addlist (&planets, p);
  }
  nl ();

  gc ();
  fprintf (stderr, "Reading Shiptypes\n");
  while (!eol)
  {
    T = alloc (sizeof (shiptype));
    gs (T->name);
    T->owner = gp ();
    T->drive = gf ();
    T->nguns = gi ();
    T->guns = gf ();
    T->shields = gf ();
    T->cargo = gf ();
    T->flag = gi ();
    T->numbuilt = gi ();
    addlist (&shiptypes, T);
  }
  nl ();
  gc ();

  fprintf (stderr, "Reading Players\n");
  while (!eol && nextc != '\n')
  {
    P = alloc (sizeof (player));
    gs (P->name);

#ifdef VERBOSE
    fprintf (stderr, "Player %s\n", P->name);
#endif

    gtech (&P->tech);
    P->opts1 = gi ();
    P->opts2 = gi ();
    P->opts3 = gi ();
    P->lastorders = gi ();
    P->homex = gf ();
    P->homey = gf ();
    P->x = gi ();
    P->y = gi ();
    P->size = gi ();
/* def mod changes */
    galliancelist (&P->allies);
    gdefendlist (&P->defend);
    ggrouplist (&P->groups);
    gcarry (&P->othertechs);
    addlist (&players, P);
  }
  gc ();
  nl ();

#ifdef KCMD
  fprintf (stderr, "Reading K-Cmds\n");
  gkcmd ();
  fprintf (stderr, "Rebuilding K-Cmds\n");
  {
    planetdefense *dp;

    for (dp = defender; dp; dp = dp->next)
    {
      cp (players, &dp->defender);
      cp (planets, &dp->planet);
    }
  }
#endif

  printf ("nextc=%c<\n", nextc);

  fprintf (stderr, "Reading Battles\n");
  while (nextc != 46)
  {
    printf ("doing a battle");
    B = alloc (sizeof (battle));
    printf ("start where\n");
    B->where = gp ();
    printf ("start gshot\n");
    gshotlist (&B->shots);
    printf ("start gviewer\n");
    gviewerlist (&B->viewers);
    printf ("start gparticipant\n");
    gparticipantlist (&B->participants);
    printf ("start addlist\n");
    addlist (&battles, B);
    printf ("finish addlist\n");
  }
  nl ();

  gc ();
  printf ("nextc=%c<\n", nextc);

  fprintf (stderr, "Reading Bombing\n");
  while (nextc != 46)
  {
    b = alloc (sizeof (bombing));
    printf ("start where\n");
    b->where = gp ();
    printf ("start who\n");
    b->who = gp ();
    b->whoose = gp ();
    b->pop = gf ();
    b->ind = gf ();
    b->col = gf ();
    b->cap = gf ();
    b->mat = gf ();
    printf ("start gviewer\n");
    gviewerlist (&b->viewers);
    addlist (&bombings, b);
    printf ("finish addlist\n");
  }
  nl ();

  gc ();
  printf ("nextc=%c<\n", nextc);

  fprintf (stderr, "Reading Fleet info\n");
  while ((nextc != 46 && nextc != '\n'))
  {
    f = alloc (sizeof (fleetname));
    gs (f->name);
    f->fleetspeed = gf ();
    f->owner = gp ();
    addlist (&fleets, f);
  }
  nl ();
  gc ();
  fprintf (stderr, "Starting planet owner/shiptype fixing\n");
  for (p = planets; p; p = p->next)
  {
    cp (players, &p->owner);
    cp (shiptypes, &p->producingshiptype);
    for (i = 0; i != MAXCARGO; i++)
      cp (planets, &p->routes[i]);
  }

  fprintf (stderr, "Reassiging Shiptype owners\n");
  for (T = shiptypes; T; T = T->next)
    cp (players, &T->owner);

  fprintf (stderr, "Reassembling alliances\n");
  for (P = players; P; P = P->next)
  {
    for (a = P->allies; a; a = a->next)
      cp (players, &a->ally);
    for (d = P->defend; d; d = d->next)
    {
      fprintf (stdout, "doing a def item\n");
      cp (players, &d->defend);
    }
    for (g = P->groups; g; g = g->next)
    {
      cp (shiptypes, &g->type);
      cp (planets, &g->from);
      cp (planets, &g->where);
    }
  }

  fprintf (stderr, "Fixing battle data\n");
  for (B = battles; B; B = B->next)
  {
    cp (planets, &B->where);
    for (S = B->shots; S; S = S->next)
    {
      cp (shiptypes, &S->attacker);
      cp (shiptypes, &S->target);
    }
    for (V = B->viewers; V; V = V->next)
      cp (players, &V->who);
    for (PA = B->participants; PA; PA = PA->next)
    {
      cp (players, &PA->who);
      for (g = PA->groups; g; g = g->next)
      {
        cp (shiptypes, &g->type);
        cp (planets, &g->from);
        cp (planets, &g->where);
      }
    }
  }

  fprintf (stderr, "Rebuilding bombing data\n");
  for (b = bombings; b; b = b->next)
  {
    cp (planets, &b->where);
    cp (players, &b->who);
    cp (players, &b->whoose);
    for (V = b->viewers; V; V = V->next)
      cp (players, &V->who);
  }

  fprintf (stderr, "Rebuilding CARRYOVER data\n");
  for (P = players; P; P = P->next)
  {
    for (t = P->othertechs; t; t = t->next)
    {
      cp (players, &t->whoose);
    }
  }
  fprintf (stderr, "Reassigning fleet ownership/group membership\n");
  for (f = fleets; f; f = f->next)
  {
    cp (players, &f->owner);
  }
  for (P = players; P; P = P->next)
    for (g = P->groups; g; g = g->next)
    {
      cp (fleets, &g->fleet);
    }
  fprintf (stderr, "Conversion complete\n");
}

int
main (int argc)
{
  fprintf (stderr, "Blind Galaxy data file ASCII to binary conversion program\n"
           "Based upon code by Russell Wallace  \n");
  inputgame ();
  sortplanets ();
  savegame ();
  return 0;
}
