/*
**  This file is part of Zterp, and is
**  Copyright 1992, 1993 Charles Hannum
*/

#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#define MAIN
#include "main.h"
#include "interpreter.h"
#include "variable.h"
#include "print.h"
#include "output.h"
#include "input.h"
#include "misc.h"


static int init = 0;

void
die (char *s, ...)
{
  va_list args;
  va_start (args, s);
  if (init)
    endwin ();
  fprintf (stderr, "fatal: ");
  vfprintf (stderr, s, args);
  fprintf (stderr, "\n");
  exit (1);
}

int
main (int argc, char **argv)
{
  char *filename;

  if (--argc != 1)
  {
    fprintf (stderr, "Usage: %s filename\n", *argv);
    exit (1);
  }

  filename = *++argv;

  {
    int fd;

    if ((fd = open (filename, O_RDONLY)) < 0)
      die ("can't open file");

    if (! (game = (zbyte *) malloc (sizeof (zheader))))
      die ("out of memory");

    if (read (fd, game, sizeof (zheader)) != sizeof (zheader))
      die ("can't read game header");

    header = (zheader *) game;

    init_screen ();
    init = 1;

    signal (SIGINT, quit);

    print_string ("This is \003Zterp\001, version 0.3 ALPHA, copyright 1992 by Charles Hannum.\n"
	          "Please read the file COPYING for usage and distribution conditions.\n"
		  "\n"
		  "Loading...");
    refresh_screen ();

    switch (zil_version)
    {
      case 1:
      case 2:
      case 3:
	zaddr_shift = 1;
	property_table_length = 0x35;
	property_length_mask = 0x20;
	property_length_shift = 5;
	property_number_mask = 0x1f;
	word_unique_length = 6;
	break;

      case 4:
      case 5:
	zaddr_shift = 2;
	property_table_length = 0x70;
	property_length_mask = 0x3f;
	property_length_shift = 6;
	property_number_mask = 0x3f;
	word_unique_length = 9;
	break;

      default:
	die ("unrecognized ZIL version %d", zil_version);
    }

    if (! (game = (zbyte *) realloc (game, game_length)))
      die ("out of memory");

    header = (zheader *) game;

    if (read (fd, game + sizeof (zheader), game_length - sizeof (zheader)) !=
	game_length - sizeof (zheader))
      die ("can't read game data");
  }

  zip_version = 1;
  zip_subversion = 'A';

  font_height = 1;
  font_width = 1;
  set_word (&header->reserved1[2], 0x0902);

  header->flags1 |= 0x20;
  if (zil_version > 3)
    header->flags1 |= 0x08;

  if (! do_verify ())
  {
    print_string ("\nGame is corrupted; aborting.\n");
    quit ();
  }
  else
  {
    print_string ("done.\n\n[Press any key to continue.]\n");
    get_character ();
    erase_window (-1);
    if (zil_version <= 3)
      split_window (1);
  }

  object = (zpointer) (near_address (object_offset + property_table_length));
  property = (zpointer) (near_address (object_offset - 2));
  variable = (zpointer) (near_address (variable_offset - (LOCAL_VARS << 1)));
  shortcut = (zpointer) (near_address (shortcut_offset));

  vocabulary = (zpointer) (near_address (vocabulary_offset));
  {
    zbyte n = get_byte (vocabulary),
	  i;
    if (! (terminators = (char *) malloc (n + 1)))
      die ("out of memory");
    terminators[0] = n;
    for (i = 0; i < n;)
      terminators[++i] = get_byte (vocabulary + i);
  }

  if (zil_version > 1)
    memcpy (alphabet, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ  0123456789.,!?_#'\"/\\-:()\0", 78);
  else
    memcpy (alphabet, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.,!?_#'\"/\\<-:()\0", 78);

  if (alphabet_offset)
  {
    zpointer p = (zpointer) (near_address (alphabet_offset));
    char *q = alphabet;
    int n = sizeof (alphabet);
    while (n--)
    {
      *(q++) = get_byte (p);
      p += 1;
    }
  }

  srand (time (0));
  random_seed[0] = (uword) rand ();
  random_seed[1] = (uword) rand ();

  sp = stack;

  interpreter_main_loop ();
}
