Exemplo n.º 1
0
Arquivo: help.c Projeto: lollek/imoria
void moria_help(vtype help_level)
{
  ntype     help_string;
  pid_t     help_pid;
  int       status;

  game_state = GS_HELP;

  sprintf(help_string, "Imoria %s", help_level);

  if ((help_pid = fork()) == 0) {
    /* child process */
    echo();
    nocbreak();
    clear_screen();
    put_qio();
    endwin();
    execlp(HELP_FILE_PATH, "mhelp.pl", help_string, 0);
    printf("\n\rUnable to execute: %s\n\r", HELP_FILE_PATH);
    printf("Press return continue.\n\r");
    fflush(stdout);
    getc(stdin);
    exit(1);
  } else if (help_pid == -1) {
    /* parent process on failure */
    msg_print("Fork failed.");
  } else {
    /* parent process on success */

#if DO_DEBUG
    fprintf(debug_file,": child: %d  watiting...\n",help_pid);
    fflush(debug_file);
#endif      
    
    waitpid(help_pid, &status, 0);  /* mhelp.pl catches ^Z and exits */
    
#if DO_DEBUG
    fprintf(debug_file,": child: %d  status 1: %d\n",
	    help_pid, status);
    fflush(debug_file);
#endif      

    waitpid(help_pid, &status, 0);  /* mhelp.pl catches ^Z and exits */
    
#if DO_DEBUG
    fprintf(debug_file,": child: %d  status 2: %d\n",
	    help_pid, status);
    fflush(debug_file);
#endif      

    cbreak();
    noecho();
    clear_screen();
    draw_cave();
  }

  //printf("\nDisplay help for %s\n\r", help_level);
};
Exemplo n.º 2
0
void top_twenty(integer this_many)
{
  /*{ Enters a players name on the top twenty list		-JWT-	}*/

  string    list[MAX_HIGH_SCORES+2];
  integer   players_line = 0;
  integer   i1,i2,i3,i4;
  int       n1;
  vtype     o1,s1;
  FILE     *f1;
  boolean   flag;
  char      ch;

  if (py.misc.cheated) {
    exit_game();
  }
  clear_screen();

  if (!read_top_scores(&f1, MORIA_TOP, list, MAX_HIGH_SCORES, &n1, s1)) {
    prt(s1,2,1);
    prt("",3,1);
  } else {

    i3   = total_points();
    flag = false;
    
    if (i3 == 0) {
      i1 = n1;
    } else {
      for (i1=1; (i1 <= n1) && !flag ; ) {   /* XXXX check for corruption */
	sscanf(&(list[i1][13]),"%ld",&i4);
	if (i4 < i3) {
	  flag = true;
	} else {
	  i1++;
	}
      }
    }

    if ((i3 > 0) && ((flag) || (n1 == 0) || (n1 < MAX_HIGH_SCORES))) {

      for (i2 = MAX_HIGH_SCORES-1; i2 >= i1 ; i2--) {
	strcpy(list[i2+1], list[i2]);
      }
      
      user_name(o1);
      
      format_top_score(list[i1], o1, i3, PM.diffic, PM.name,
		       PM.lev, PM.race, PM.tclass);
      
      if (n1 < MAX_HIGH_SCORES) {
	n1++;
      }

      max_score    = n1;
      players_line = i1;
      flag         = false;

      write_top_scores(&f1, list, n1);

    } else { 
      /* did not get a high score */
      max_score = 20;
    }      
    
    if (!close_top_scores(&f1)) {
      prt("Error unlocking score file.",2,1);
      prt("",3,1);
    }
    
    put_buffer("Username     Points  Diff    Character name    Level  Race         Class",1,1);
    put_buffer("____________ ________ _ ________________________ __ __________ ________________",2,1);
    
    i2 = 3;
    if (max_score > n1) {
      max_score = n1;
    }
    
    if (this_many > 0) {
      if (this_many > MAX_HIGH_SCORES) {
	max_score = MAX_HIGH_SCORES;
      } else {
	max_score = this_many;
      }
    }
    for (i1 = 1; i1 <= max_score; i1++) {
      /*insert_str(list[i1],chr(7),''); XXXX  why? */
      if (i1 == players_line) {
	put_buffer_attr(list[i1],i2,1, A_REVERSE);
      } else {
	put_buffer(list[i1],i2,1);
      }
      if ((i1 != 1) && ((i1 % 20) == 0) && (i1 != max_score)) {
	prt("[Press any key to continue, or <Control>-Z to exit]",
	    24,1);
	ch = inkey();
	switch (ch) {
	case 3: case 25: case 26:
	  erase_line(24,1);
	  put_buffer(" ",23,13);
	  exit_game();
	  break;
	}
	clear_rc(3,1);
	i2 = 2;
      }
      i2++;
    } /* end for */
    
    erase_line(23,1);
    put_qio();
    
  } /* end if read_top_scores */
};
Exemplo n.º 3
0
Arquivo: map.c Projeto: MrDrews/umoria
/* Prints dungeon map to external file			-RAK-	 */
print_map()
{
  register int i, j, m, n;
  register k, l;
  register i7, i8;
  char dun_line[MAX_WIDTH+1];
  char *dun_ptr;
  static vtype filename1 = "MORIAMAP.DAT";
  vtype filename2;
  char tmp_str[80];
  FILE *file1;
  static int page_width = OUTPAGE_WIDTH;
  static int page_height = OUTPAGE_HEIGHT;

  /* this allows us to strcat each character in the inner loop,
     instead of using the expensive sprintf */
  (void) sprintf (tmp_str, "File name [%s]: ", filename1);
  prt(tmp_str, 0, 0);
  if (get_string(filename2, 0, strlen(tmp_str), 64))
    {
      if (strlen(filename2) > 0)
	(void) strcpy(filename1, filename2);
      if ((file1 = fopen(filename1, "w")) == NULL)
	{
	  (void) sprintf(dun_line, "Cannot open file %s", filename1);
	  prt(dun_line, 0, 0);
	  return;
	}
      (void) sprintf(tmp_str, "section width (default = %d char):",
		     page_width);
      prt(tmp_str, 0, 0);
      (void) get_string(tmp_str, 0, strlen(tmp_str), 10);
      page_width = atoi(tmp_str);
      if (page_width < 10)
	page_width = 10;

      (void) sprintf(tmp_str, "section height (default = %d lines):",
		     page_height);
      prt(tmp_str, 0, 0);
      (void) get_string(tmp_str, 0, strlen(tmp_str), 10);
      page_height = atoi(tmp_str);
      if (page_height < 10)
	page_height = 10;

      prt("Writing Moria Dungeon Map...", 0, 0);
      put_qio();

      i = 0;
      i7 = 0;
      do
	{
	  j = 0;
	  k = i + page_height - 1;
	  if (k >= cur_height)
	    k = cur_height - 1;
	  i7++;
	  i8 = 0;
	  do
	    {
	      l = j + page_width - 1;
	      if (l >= cur_width)
		l = cur_width - 1;
	      i8++;
	      (void) fprintf(file1, "%c\n", CTRL('L'));
	      (void) fprintf(file1, "Section[%d,%d];     ", i7, i8);
	      (void) fprintf(file1, "Depth : %d (feet)\n\n   ",
			     (dun_level * 50));
	      for (m = j; m <= l; m++)
		{
		  n = (m / 100);
		  (void) fprintf(file1, "%d", n);
		}
	      (void) fputs("\n   ", file1);
	      for (m = j; m <= l; m++)
		{
		  n = (m / 10) - (m / 100) * 10;
		  (void) fprintf(file1, "%d", n);
		}
	      (void) fputs("\n   ", file1);
	      for (m = j; m <= l; m++)
		{
		  n = m - (m / 10) * 10;
		  (void) fprintf(file1, "%d", n);
		}
	      (void) fprintf(file1, "\n");
	      for (m = i; m <= k; m++)
		{
		  (void) sprintf(dun_line, "%2d ", m);
		  dun_ptr = &dun_line[3];
		  for (n = j; n <= l; n++)
		    *dun_ptr++ = loc_symbol(m, n);
		  *dun_ptr++ = '\n';
		  *dun_ptr++ = '\0';
		  (void) fputs(dun_line, file1);
		}
	      j += page_width;
	    }
	  while (j < cur_width);
	  i += page_height;
	}
      while (i < cur_height);
      (void) fclose(file1);
      prt("Completed.", 0, 0);
    }
}
Exemplo n.º 4
0
/* Wizard command for restoring character    -RAK- */
int restore_char()
{
    vtype fnam;
    int i;
    int j;
    FILE *f1;
    int error;
    vtype temp;
    double version;
    struct stat buf2;
    char char_tmp;
    char char_tmp_array[3];
    cave_type *c_ptr;

    clear_screen(0, 0);
    prt("Enter Filename:", 0, 0);

    if(!get_string(fnam, 0, 16, 60)) {
	return FALSE;
    }

    no_controlz();

    if(chmod(fnam, (IREAD | IWRITE)) == -1) {
	sprintf(temp, "Can not change file mode for %s", fnam);
	prt(temp, 0, 0);
    }

    f1 = fopen(fnam, "r");

    if(f1 == NULL) {
	sprintf(temp, "Cannot open file %s for reading.", fnam);
	prt(temp, 0, 0);

	return FALSE;
    }

    prt("Restoring Character...", 0, 0);
    put_qio();
    error = 0;
    error |= !fread((char *)&version, sizeof(version), 1, f1);
    error |= !fread((char *)&py, sizeof(py), 1, f1);
    error |= !fread((char *)&char_row, sizeof(char_row), 1, f1);
    error |= !fread((char *)&char_col, sizeof(char_col), 1, f1);
    error |= !fread((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
    error |= !fread((char *)&inven_weight, sizeof(inven_weight), 1, f1);
    error |= !fread((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
    error |= !fread((char *)&dun_level, sizeof(dun_level), 1, f1);
    error |= !fread((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
    error |= !fread((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
    error |= !fread((char *)&turn, sizeof(turn), 1, f1);
    error |= !fread((char *)inventory, sizeof(inventory), 1, f1);
    error |= !fread((char *)magic_spell[py.misc.pclass], sizeof(spell_type), 31, f1);
    error |= !fread((char *)&cur_height, sizeof(cur_height), 1, f1);
    error |= !fread((char *)&cur_width, sizeof(cur_width), 1, f1);
    error |= !fread((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
    error |= !fread((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);

    for(i = 0; i < MAX_HEIGHT; ++i) {
	for(j = 0; j < MAX_WIDTH; ++j) {
	    c_ptr = &cave[i][j];
	    error |= !fread((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
	    error |= !fread((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
	    error |= !fread((char *)&char_tmp, sizeof(char_tmp), 1, f1);
	    c_ptr->fval = char_tmp & 0xF;
	    c_ptr->fopen = (char_tmp >> 4) & 0x1;
	    c_ptr->fm = (char_tmp >> 5) & 0x1;
	    c_ptr->pl = (char_tmp >> 6) & 0x1;
	    c_ptr->tl = (char_tmp >> 7) & 0x1;
	}
    }

    error |= !fread((char *)t_list, sizeof(t_list), 1, f1);
    error |= !fread((char *)&tcptr, sizeof(tcptr), 1, f1);
    error |= !fread((char *)object_ident, sizeof(object_ident), 1, f1);
    error |= !fread((char *)m_list, sizeof(m_list), 1, f1);
    error |= !fread((char *)&mfptr, sizeof(mfptr), 1, f1);
    error |= !fread((char *)&muptr, sizeof(muptr), 1, f1);

    if(version == 4.83) {
	/* insult_cur was a byte in 4.83, but is now a short */
	for(i = 0; i < MAX_STORES; ++i) {
	    error |= !fread((char *)&store[i].store_open, sizeof(short), 1, f1);

	    /* This is different */
	    error |= !fread((char *)&char_tmp, sizeof(char), 1, f1);
	    store[i].insult_cur = (short)char_tmp;
	    error |= !fread((char *)&store[i].owner, sizeof(char), 1, f1);
	    error |= !fread((char *)&store[i].store_ctr, sizeof(char), 1, f1);

	    /* 
	     * Quick compatibility hack for a local vax ignore three bytes of
	     * fill character
	     */
	    error |= !fread((char *)char_tmp_array, sizeof(char), 3, f1);
	    error |= !fread((char *)store[i].store_inven, sizeof(inven_record), STORE_INVEN_MAX, f1);
	}
    }
    else {
	error |= !fread((char *)store, sizeof(store), 1, f1);
    }

    error |= !fread((char *)&buf2, sizeof(buf2), 1, f1);
    error |= !fread((char *)norm_state, sizeof(norm_state), 1, f1);
    error |= !fread((char *)randes_state, sizeof(randes_state), 1, f1);
    error |= !fread((char *)&randes_state, sizeof(randes_seed), 1, f1);
    error |= !fread((char *)town_state, sizeof(town_state), 1, f1);
    error |= !fread((char *)&town_seed, sizeof(town_seed), 1, f1);

    if(version >= 4.87) {
	error |= fread((char *)&panic_save, sizeof(panic_save), 1, f1);

	/* Clear the panic_save condition, which is used to indicate cheating */
	panic_save = 0;
    }

    error |= fclose(f1);
    controlz();

    if(error) {
	sprintf(temp, "Error reading in file %s", fnam);
	prt(temp, 0, 0);

	return FALSE;
    }

    if(unlink(fnam) == -1) {
	sprintf(temp, "Cannot delete file %s", fnam);
	prt(temp, 0, 0);
    }

    /* 
     * Reidentify objects.
     * very inefficient, should write new routine perhaps? 
     */
    for(i = 0; i < MAX_OBJECTS; ++i) {
	if(object_ident[i] == TRUE) {
	    identify(object_list[i]);
	}
    }

    return FALSE;
}
Exemplo n.º 5
0
int get_char(char *fnam)
{
    int i;
    int j;
    FILE *f1;
    int error;
    vtype temp;
    double version;

#ifdef USG
    struct stat buf;
    struct stat buf2;

#else

    struct stat lbuf;
    struct stat buf;
    struct stat buf2;
#endif

    char char_tmp;
    char char_tmp_array[3];
    cave_type *c_ptr;
    long age;

    clear_screen(0, 0);
    no_controlz();

#ifdef USG
    /* No symbolic links */
    if(stat(fnam, &buf) == -1) {
	sprintf(temp, "Cannot stat file &s", fnam);
	prt(temp, 0, 0);

	exit_game();
    }
    
#else

    if((lstat(fnam, &lbuf) == -1) || (stat(fnam, &buf) == -1)) {
	sprintf(temp, "Cannot stat file %s", fnam);
	prt(temp, 0, 0);

	exit_game();
    }
#endif

#ifdef USG
    /* No symbolic links */
    
#else
    
    if(lbuf.st_ino != buf.st_ino) {
	sprintf(temp, "Cannot restore from symbolic link %s", fnam);
	prt(temp, 0, 0);

	exit_game();
    }
#endif

    if(buf.st_nlink != 1) {
	sprintf(temp, "Too many links to file %s", fnam);
	prt(temp, 0, 0);

	exit_game();
    }

    if(chmod(fnam, (IREAD | IWRITE)) == -1) {
	sprintf(temp, "Can not change file mode for %s", fnam);
	prt(temp, 0, 0);
    }

    f1 = fopen(fnam, "r");

    if(f1 == NULL) {
	sprintf(temp, "Cannot open file %s for reading", fnam);
	prt(temp, 0, 0);

	exit_game();
    }

    prt("Restoring Character...", 0, 0);
    put_qio();
    error = 0;
    error |= !fread((char *)&version, sizeof(version), 1, f1);
    error |= !fread((char *)&py, sizeof(py), 1, f1);
    error |= !fread((char *)&char_row, sizeof(char_row), 1, f1);
    error |= !fread((char *)&char_col, sizeof(char_col), 1, f1);
    error |= !fread((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
    error |= !fread((char *)&inven_weight, sizeof(inven_weight), 1, f1);
    error |= !fread((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
    error |= !fread((char *)&dun_level, sizeof(dun_level), 1, f1);
    error |= !fread((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
    error |= !fread((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
    error |= !fread((char *)&turn, sizeof(turn), 1, f1);
    error |= !fread((char *)inventory, sizeof(inventory), 1, f1);
    error |= !fread((char *)magic_spell[py.misc.pclass], sizeof(spell_type), 31, f1);
    error |= !fread((char *)&cur_height, sizeof(cur_height), 1, f1);
    error |= !fread((char *)&cur_width, sizeof(cur_width), 1, f1);
    error |= !fread((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
    error |= !fread((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);

    for(i = 0; i < MAX_HEIGHT; ++i) {
	for(j = 0; j < MAX_WIDTH; ++j) {
	    c_ptr = &cave[i][j];
	    error |= !fread((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
	    error |= !fread((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
	    error |= !fread((char *)&char_tmp, sizeof(char_tmp), 1, f1);
	    c_ptr->fval = char_tmp & 0xF;
	    c_ptr->fopen = (char_tmp >> 4) & 0x1;
	    c_ptr->fm = (char_tmp >> 5) & 0x1;
	    c_ptr->pl = (char_tmp >> 6) & 0x1;
	    c_ptr->tl = (char_tmp >> 7) & 0x1;
	}
    }

    error |= !fread((char *)t_list, sizeof(t_list), 1, f1);
    error |= !fread((char *)&tcptr, sizeof(tcptr), 1, f1);
    error |= !fread((char *)object_ident, sizeof(object_ident), 1, f1);
    error |= !fread((char *)m_list, sizeof(m_list), 1, f1);
    error |= !fread((char *)&mfptr, sizeof(mfptr), 1, f1);
    error |= !fread((char *)&muptr, sizeof(muptr), 1, f1);

    if(version == 4.83) {
	/* insult_cur was a byte in 4.83, but is now a short */
	for(i = 0; i < MAX_STORES; ++i) {
	    error |= !fread((char *)&store[i].store_open, sizeof(short), 1, f1);

	    /* This is different */
	    error |= !fread((char *)&char_tmp, sizeof(char), 1, f1);
	    store[i].insult_cur = (short)char_tmp;
	    error |= !fread((char *)&store[i].owner, sizeof(char), 1, f1);
	    error |= !fread((char *)&store[i].store_ctr, sizeof(char), 1, f1);

	    /*
	     * Quick compatibility hack for a local vax ignore three bytes of
	     * fill character
	     */
	    error |= !fread((char *)char_tmp_array, sizeof(char), 3, f1);
	    error |= !fread((char *)store[i].store_inven, sizeof(inven_record), STORE_INVEN_MAX, f1);
	}
    }
    else {
	error |= !fread((char *)store, sizeof(store), 1, f1);
    }

    error |= !fread((char *)&buf2, sizeof(buf2), 1, f1);
    error |= !fread((char *)norm_state, sizeof(norm_state), 1, f1);
    error |= !fread((char *)randes_state, sizeof(randes_state), 1, f1);
    error |= !fread((char *)&randes_seed, sizeof(randes_seed), 1, f1);
    error |= !fread((char *)town_state, sizeof(town_state), 1, f1);
    error |= !fread((char *)&town_seed, sizeof(town_seed), 1, f1);

    if(version >= 4.87) {
	error |= !fread((char *)&panic_save, sizeof(panic_save), 1, f1);
    }

    error |= fclose(f1);
    controlz();

    if(buf.st_atime >= (buf2.st_atime + 5)) {
	sprintf(temp, "File %s has been touched, sorry.", fnam);
	prt(temp, 0, 0);

	exit_game();
    }

    if(error) {
	sprintf(temp, "Error reading in file %s", fnam);
	prt(temp, 0, 0);

	exit_game();
    }

    /*
     * Rotate store inventory, depending on how old the save file is foreach day
     * or fraction thereof old, call store_maint once must do this before delete
     * file
     */
    if(stat(fnam, &buf2) == -1) {
	sprintf(temp, "Cannot stat file %s?", fnam);
	prt(temp, 0, 0);
    }
    else {
	/* Age in seconds */
	age = (long)buf2.st_atime - (long)buf.st_atime;

	/* Age in days */
	age = (age / 86400) + 1;

	for(i = 0; i < age; ++i) {
	    store_maint();
	}
    }

    if(unlink(fnam) == -1) {
	sprintf(temp, "Cannot delete file %s", fnam);
	prt(temp, 0, 0);

	exit_game();
    }

    if(panic_save == 1) {
	sprintf(temp, "This game is from a panic save. Score will not be added to scoreboard.");
	msg_print(temp);

	/* Make sure player will see message before change_name is called */
	msg_print(" ");
    }

    /* 
     * Reidentify objects.
     * Very inefficient, should write new routine perhaps?
     */
    for(i = 0; i < MAX_OBJECTS; ++i) {
	if(object_ident[i] == TRUE) {
	    identify(object_list[i]);
	}
    }

    /*
     * In case restoring a dead character, this can happen if a signal is caught
     * after a character's hit points go below zero, but before the game ends
     */
    if(py.misc.chp <= -1) {
	prt("Your character has already died.", 23, 0);
	strcpy(died_from, "Unknown.");
	death = 1;
    }

    return FALSE;
}
Exemplo n.º 6
0
void save_char(int exit, int no_ask)
{
    int i;
    int j;
    int flag;
    int error;
    vtype fnam;
    vtype temp;
    double version;
    struct stat buf;
    FILE *f1;
    char char_tmp;
    cave_type *c_ptr;

    flag = FALSE;

    if(!no_ask) {
	prt("Enter Filename:", 0, 0);

	if(!get_string(fnam, 0, 16, 60)) {
	    /* Only return if exit TRUE, i.e. this is not a panic save */
	    if(exit) {
		return;
	    }
	    else {
		strcpy(fnam, "MORIACHR.SAV");
	    }
	}
	else if(strlen(fnam) == 0) {
	    /* If get_string succeeded, but returned zero length */
	    strcpy(fnam, "MORIACHR.SAV");
	}
    }
    else {
	strcpy(fnam, "MORIACHR.SAV");
    }

    no_controlz();

    /* Open the user's save file    -JEW- */
    f1 = fopen(fnam, "w");

    if(f1 == NULL) {
	sprintf(temp, "Error creating %s", fnam);
	msg_print(temp);

	return;
    }

    flag = TRUE;
    clear_screen(0, 0);
    prt("Saving character...", 0, 0);
    put_qio();
    version = CUR_VERSION;
    error = 0;
    error |= !fwrite((char *)&version, sizeof(version), 1, f1);
    error |= !fwrite((char *)&py, sizeof(py), 1, f1);
    error |= !fwrite((char *)&char_row, sizeof(char_row), 1, f1);
    error |= !fwrite((char *)&char_col, sizeof(char_col), 1, f1);
    error |= !fwrite((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
    error |= !fwrite((char *)&inven_weight, sizeof(inven_weight), 1, f1);
    error |= !fwrite((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
    error |= !fwrite((char *)&dun_level, sizeof(dun_level), 1, f1);
    error |= !fwrite((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
    error |= !fwrite((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
    error |= !fwrite((char *)&turn, sizeof(turn), 1, f1);
    error |= !fwrite((char *)inventory, sizeof(inventory), 1, f1);
    error |= !fwrite((char *)magic_spell[py.misc.pclass], sizeof(spell_type), 31, f1);
    error |= !fwrite((char *)&cur_height, sizeof(cur_height), 1, f1);
    error |= !fwrite((char *)&cur_width, sizeof(cur_width), 1, f1);
    error |= !fwrite((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
    error |= !fwrite((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);

    for(i = 0; i < MAX_HEIGHT; ++i) {
	for(j = 0; j < MAX_WIDTH; ++j) {
	    c_ptr = &cave[i][j];
	    char_tmp = c_ptr->fval | (c_ptr->fopen << 4) | (c_ptr->fm << 5) | (c_ptr->pl << 6) | (c_ptr->tl << 7);
	    error |= !fwrite((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
	    error |= !fwrite((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
	    error |= !fwrite((char *)&char_tmp, sizeof(char_tmp), 1, f1);
	}
    }

    error |= !fwrite((char *)t_list, sizeof(t_list), 1, f1);
    error |= !fwrite((char *)&tcptr, sizeof(tcptr), 1, f1);
    error |= !fwrite((char *)object_ident, sizeof(object_ident), 1, f1);
    error |= !fwrite((char *)m_list, sizeof(m_list), 1, f1);
    error |= !fwrite((char *)&mfptr, sizeof(mfptr), 1, f1);
    error |= !fwrite((char *)&muptr, sizeof(muptr), 1, f1);
    error |= !fwrite((char *)store, sizeof(store), 1, f1);

    if(stat(fnam, &buf) == -1) {
	sprintf(temp, "Can not stat file %s", fnam);
	msg_print(temp);

	return;
    }

    error |= !fwrite((char *)&buf, sizeof(buf), 1, f1);
    error |= !fwrite((char *)norm_state, sizeof(norm_state), 1, f1);
    error |= !fwrite((char *)randes_state, sizeof(randes_state), 1, f1);
    error |= !fwrite((char *)&randes_seed, sizeof(randes_seed), 1, f1);
    error |= !fwrite((char *)town_state, sizeof(town_state), 1, f1);
    error |= !fwrite((char *)&town_seed, sizeof(town_seed), 1, f1);

    /* This indicates 'cheating' if it is a one */
    error |= !fwrite((char *)&panic_save, sizeof(panic_save), 1, f1);
    error |= fclose(f1);
    character_saved = 1;

    if(!wizard1) {
	if(chmod(fnam, 0) == -1) {
	    sprintf(temp, "Can not change file mode for %s", fnam);
	    msg_print(temp);

	    return;
	}
    }

    /* Make sure user can't touch save file for 5 seconds */
    sleep(5);
    controlz();

    if(error) {
	sprintf(temp, "Error writing to file %s", fnam);
	prt(temp, 0, 0);
	prt("Game not saved.", 0, 0);
    }
    else if(flag) {
	sprintf(temp, "Character saved. [Moria Version %lf]", CUR_VERSION);
	prt(temp, 0, 0);

	if(exit) {
	    exit_game();
	}
    }
}