/* settings.c: Handling configuration settings
   Copyright (c) Copyright (c) 2002 Philip Kendall

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 49 Temple Place, Suite 330, Boston, MA 02111-1307 USA

   Author contact information:

   E-mail: pak21-fuse@srcf.ucam.org
   Postal address: 15 Crescent Road, Wokingham, Berks, RG40 2DB, England

*/
#line 66"settings.pl"

/* This file is autogenerated from settings.dat by settings.pl.
   Do not edit unless you know what will happen! */

#include <config.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#ifdef HAVE_GETOPT_LONG		/* Did our libc include getopt_long? */
#include <getopt.h>
#else				/* #ifdef HAVE_GETOPT_LONG */
#include "compat.h"		/* If not, use ours */
#endif				/* #ifdef HAVE_GETOPT_LONG */

#ifdef HAVE_LIB_XML2
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#endif				/* #ifdef HAVE_LIB_XML2 */

#include "fuse.h"
#include "machine.h"
#include "settings.h"
#include "spectrum.h"
#include "ui/ui.h"
#include "utils.h"

/* The name of our configuration file */
#ifdef WIN32
#define CONFIG_FILE_NAME "fuse.cfg"
#else				/* #ifdef WIN32 */
#define CONFIG_FILE_NAME ".fuserc"
#endif				/* #ifdef WIN32 */

/* The current settings of options, etc */
settings_info settings_current;

#ifdef HAVE_LIB_XML2
static int read_config_file( settings_info *settings );
static int parse_xml( xmlDocPtr doc, settings_info *settings );
#endif				/* #ifdef HAVE_LIB_XML2 */

static int settings_command_line( settings_info *settings, int *first_arg,
				  int argc, char **argv );

/* Called on emulator startup */
int
settings_init( int *first_arg, int argc, char **argv )
{
  int error;

  error = settings_defaults( &settings_current );
  if( error ) {
    ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ );
    return error;
  }

#ifdef HAVE_LIB_XML2
  error = read_config_file( &settings_current );
  if( error ) return error;
#endif				/* #ifdef HAVE_LIB_XML2 */

  error = settings_command_line( &settings_current, first_arg, argc, argv );
  if( error ) return error;

  return 0;
}

/* Fill the settings structure with sensible defaults */
int settings_defaults( settings_info *settings )
{
  settings->aspect_hint = 1;
  settings->auto_load = 1;
  settings->autosave_settings = 0;
  settings->bw_tv = 0;
  settings->competition_code = 0;
  settings->competition_mode = 0;
  settings->confirm_actions = 1;
  settings->dck_file = NULL;
  settings->embed_snapshot = 1;
  settings->emulation_speed = 100;
  settings->frame_rate = 1;
  settings->full_screen = 0;
  settings->if2_file = NULL;
  settings->interface2 = 1;
  settings->issue2 = 0;
  settings->joy_kempston = 0;
  settings->joystick_1 = NULL;
  settings->joystick_1_fire_1 = 4096;
  settings->joystick_1_fire_10 = 4096;
  settings->joystick_1_fire_2 = 4096;
  settings->joystick_1_fire_3 = 4096;
  settings->joystick_1_fire_4 = 4096;
  settings->joystick_1_fire_5 = 4096;
  settings->joystick_1_fire_6 = 4096;
  settings->joystick_1_fire_7 = 4096;
  settings->joystick_1_fire_8 = 4096;
  settings->joystick_1_fire_9 = 4096;
  settings->joystick_1_output = 0;
  settings->joystick_2 = NULL;
  settings->joystick_2_fire_1 = 4096;
  settings->joystick_2_fire_10 = 4096;
  settings->joystick_2_fire_2 = 4096;
  settings->joystick_2_fire_3 = 4096;
  settings->joystick_2_fire_4 = 4096;
  settings->joystick_2_fire_5 = 4096;
  settings->joystick_2_fire_6 = 4096;
  settings->joystick_2_fire_7 = 4096;
  settings->joystick_2_fire_8 = 4096;
  settings->joystick_2_fire_9 = 4096;
  settings->joystick_2_output = 0;
  settings->joystick_keyboard_output = 0;
  settings->playback_file = NULL;
  settings->plus3disk_file = NULL;
  settings->printer = 0;
  settings->printer_graphics_filename = strdup( "printout.pbm" );
  if( !settings->printer_graphics_filename ) return 1;
  settings->printer_text_filename = strdup( "printout.txt" );
  if( !settings->printer_text_filename ) return 1;
  settings->record_file = NULL;
  settings->rom_128_0 = strdup( "128-0.rom" );
  if( !settings->rom_128_0 ) return 1;
  settings->rom_128_1 = strdup( "128-1.rom" );
  if( !settings->rom_128_1 ) return 1;
  settings->rom_16 = strdup( "48.rom" );
  if( !settings->rom_16 ) return 1;
  settings->rom_48 = strdup( "48.rom" );
  if( !settings->rom_48 ) return 1;
  settings->rom_pentagon_0 = strdup( "128p-0.rom" );
  if( !settings->rom_pentagon_0 ) return 1;
  settings->rom_pentagon_1 = strdup( "128p-1.rom" );
  if( !settings->rom_pentagon_1 ) return 1;
  settings->rom_pentagon_2 = strdup( "trdos.rom" );
  if( !settings->rom_pentagon_2 ) return 1;
  settings->rom_plus2_0 = strdup( "plus2-0.rom" );
  if( !settings->rom_plus2_0 ) return 1;
  settings->rom_plus2_1 = strdup( "plus2-1.rom" );
  if( !settings->rom_plus2_1 ) return 1;
  settings->rom_plus2a_0 = strdup( "plus3-0.rom" );
  if( !settings->rom_plus2a_0 ) return 1;
  settings->rom_plus2a_1 = strdup( "plus3-1.rom" );
  if( !settings->rom_plus2a_1 ) return 1;
  settings->rom_plus2a_2 = strdup( "plus3-2.rom" );
  if( !settings->rom_plus2a_2 ) return 1;
  settings->rom_plus2a_3 = strdup( "plus3-3.rom" );
  if( !settings->rom_plus2a_3 ) return 1;
  settings->rom_plus3_0 = strdup( "plus3-0.rom" );
  if( !settings->rom_plus3_0 ) return 1;
  settings->rom_plus3_1 = strdup( "plus3-1.rom" );
  if( !settings->rom_plus3_1 ) return 1;
  settings->rom_plus3_2 = strdup( "plus3-2.rom" );
  if( !settings->rom_plus3_2 ) return 1;
  settings->rom_plus3_3 = strdup( "plus3-3.rom" );
  if( !settings->rom_plus3_3 ) return 1;
  settings->rom_plus3e_0 = strdup( "plus3e-0.rom" );
  if( !settings->rom_plus3e_0 ) return 1;
  settings->rom_plus3e_1 = strdup( "plus3e-1.rom" );
  if( !settings->rom_plus3e_1 ) return 1;
  settings->rom_plus3e_2 = strdup( "plus3e-2.rom" );
  if( !settings->rom_plus3e_2 ) return 1;
  settings->rom_plus3e_3 = strdup( "plus3e-3.rom" );
  if( !settings->rom_plus3e_3 ) return 1;
  settings->rom_scorpion_0 = strdup( "256s-0.rom" );
  if( !settings->rom_scorpion_0 ) return 1;
  settings->rom_scorpion_1 = strdup( "256s-1.rom" );
  if( !settings->rom_scorpion_1 ) return 1;
  settings->rom_scorpion_2 = strdup( "256s-2.rom" );
  if( !settings->rom_scorpion_2 ) return 1;
  settings->rom_scorpion_3 = strdup( "256s-3.rom" );
  if( !settings->rom_scorpion_3 ) return 1;
  settings->rom_spec_se_0 = strdup( "se-0.rom" );
  if( !settings->rom_spec_se_0 ) return 1;
  settings->rom_spec_se_1 = strdup( "se-1.rom" );
  if( !settings->rom_spec_se_1 ) return 1;
  settings->rom_tc2048 = strdup( "tc2048.rom" );
  if( !settings->rom_tc2048 ) return 1;
  settings->rom_tc2068_0 = strdup( "tc2068-0.rom" );
  if( !settings->rom_tc2068_0 ) return 1;
  settings->rom_tc2068_1 = strdup( "tc2068-1.rom" );
  if( !settings->rom_tc2068_1 ) return 1;
  settings->rzx_compression = 0;
  settings->simpleide_active = 0;
  settings->simpleide_master_file = NULL;
  settings->simpleide_slave_file = NULL;
  settings->slt_traps = 1;
  settings->snaps_as_z80 = 0;
  settings->snapshot = NULL;
  settings->sound = 1;
  settings->sound_device = NULL;
  settings->sound_force_8bit = 0;
  settings->sound_load = 1;
  settings->start_machine = strdup( "48" );
  if( !settings->start_machine ) return 1;
  settings->start_scaler_mode = strdup( "normal" );
  if( !settings->start_scaler_mode ) return 1;
  settings->statusbar = 1;
  settings->stereo_ay = 0;
  settings->stereo_beeper = 0;
  settings->svga_mode = 320;
  settings->tape_file = NULL;
  settings->tape_traps = 1;
  settings->trdosdisk_file = NULL;
  settings->writable_roms = 0;
  settings->zxatasp_active = 0;
  settings->zxatasp_master_file = NULL;
  settings->zxatasp_slave_file = NULL;
  settings->zxatasp_upload = 0;
  settings->zxatasp_wp = 0;
  settings->zxcf_active = 0;
  settings->zxcf_pri_file = NULL;
  settings->zxcf_upload = 0;
#line 154"settings.pl"
  
#ifdef HAVE_LIBZ
  settings->rzx_compression = 1;
#endif			/* #ifdef HAVE_LIBZ */

  return 0;
}

#ifdef HAVE_LIB_XML2

/* Read options from the config file (if libxml2 is available) */

static int
read_config_file( settings_info *settings )
{
  const char *home; char path[256];
  struct stat stat_info;

  xmlDocPtr doc;

  home = utils_get_home_path(); if( !home ) return 1;

  snprintf( path, 256, "%s/%s", home, CONFIG_FILE_NAME );

  /* See if the file exists; if doesn't, it's not a problem */
  if( stat( path, &stat_info ) ) {
    if( errno == ENOENT ) {
      return 0;
    } else {
      ui_error( UI_ERROR_ERROR, "couldn't stat '%s': %s", path,
		strerror( errno ) );
      return 1;
    }
  }

  doc = xmlParseFile( path );
  if( !doc ) {
    ui_error( UI_ERROR_ERROR, "error reading config file" );
    return 1;
  }

  if( parse_xml( doc, settings ) ) { xmlFreeDoc( doc ); return 1; }

  xmlFreeDoc( doc );

  return 0;
}

static int
parse_xml( xmlDocPtr doc, settings_info *settings )
{
  xmlNodePtr node;
  const char *string;

  node = xmlDocGetRootElement( doc );
  if( xmlStrcmp( node->name, (const xmlChar*)"settings" ) ) {
    ui_error( UI_ERROR_ERROR, "config file's root node is not 'settings'" );
    return 1;
  }

  node = node->xmlChildrenNode;
  while( node ) {

    if( !strcmp( node->name, (const xmlChar*)"aspecthint" ) ) {
      settings->aspect_hint = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"autoload" ) ) {
      settings->auto_load = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"autosavesettings" ) ) {
      settings->autosave_settings = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"bwtv" ) ) {
      settings->bw_tv = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"competitioncode" ) ) {
      settings->competition_code = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"competitionmode" ) ) {
      settings->competition_mode = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"confirmactions" ) ) {
      settings->confirm_actions = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"dock" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->dck_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"doublescreen" ) ) {
      /* Do nothing */
    } else
    if( !strcmp( node->name, (const xmlChar*)"embedsnapshot" ) ) {
      settings->embed_snapshot = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"speed" ) ) {
      settings->emulation_speed = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"rate" ) ) {
      settings->frame_rate = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"fullscreen" ) ) {
      settings->full_screen = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"if2cart" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->if2_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"interface2" ) ) {
      settings->interface2 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"issue2" ) ) {
      settings->issue2 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"kempston" ) ) {
      settings->joy_kempston = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->joystick_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire1" ) ) {
      settings->joystick_1_fire_1 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire10" ) ) {
      settings->joystick_1_fire_10 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire2" ) ) {
      settings->joystick_1_fire_2 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire3" ) ) {
      settings->joystick_1_fire_3 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire4" ) ) {
      settings->joystick_1_fire_4 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire5" ) ) {
      settings->joystick_1_fire_5 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire6" ) ) {
      settings->joystick_1_fire_6 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire7" ) ) {
      settings->joystick_1_fire_7 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire8" ) ) {
      settings->joystick_1_fire_8 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1fire9" ) ) {
      settings->joystick_1_fire_9 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick1output" ) ) {
      settings->joystick_1_output = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->joystick_2 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire1" ) ) {
      settings->joystick_2_fire_1 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire10" ) ) {
      settings->joystick_2_fire_10 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire2" ) ) {
      settings->joystick_2_fire_2 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire3" ) ) {
      settings->joystick_2_fire_3 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire4" ) ) {
      settings->joystick_2_fire_4 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire5" ) ) {
      settings->joystick_2_fire_5 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire6" ) ) {
      settings->joystick_2_fire_6 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire7" ) ) {
      settings->joystick_2_fire_7 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire8" ) ) {
      settings->joystick_2_fire_8 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2fire9" ) ) {
      settings->joystick_2_fire_9 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystick2output" ) ) {
      settings->joystick_2_output = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"joystickkeyboardoutput" ) ) {
      settings->joystick_keyboard_output = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"playbackfile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->playback_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"plus3disk" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->plus3disk_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"printer" ) ) {
      settings->printer = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"graphicsfile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->printer_graphics_filename = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"textfile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->printer_text_filename = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"recordfile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->record_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rom1280" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_128_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rom1281" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_128_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rom16" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_16 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rom48" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_48 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rompentagon0" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_pentagon_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rompentagon1" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_pentagon_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"rompentagon2" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_pentagon_2 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus20" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus2_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus21" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus2_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus2a0" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus2a_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus2a1" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus2a_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus2a2" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus2a_2 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus2a3" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus2a_3 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus30" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus31" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus32" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3_2 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus33" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3_3 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus3e0" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3e_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus3e1" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3e_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus3e2" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3e_2 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romplus3e3" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_plus3e_3 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romscorpion0" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_scorpion_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romscorpion1" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_scorpion_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romscorpion2" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_scorpion_2 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romscorpion3" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_scorpion_3 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romspecse0" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_spec_se_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romspecse1" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_spec_se_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romtc2048" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_tc2048 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romtc20680" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_tc2068_0 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"romtc20681" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->rom_tc2068_1 = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"compressrzx" ) ) {
      settings->rzx_compression = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"simpleide" ) ) {
      settings->simpleide_active = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"simpleidemasterfile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->simpleide_master_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"simpleideslavefile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->simpleide_slave_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"slttraps" ) ) {
      settings->slt_traps = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"snapsasz80" ) ) {
      settings->snaps_as_z80 = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"snapshot" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->snapshot = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"sound" ) ) {
      settings->sound = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"sounddevice" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->sound_device = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"soundforce8bit" ) ) {
      settings->sound_force_8bit = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"loadingsound" ) ) {
      settings->sound_load = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"machine" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->start_machine = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"graphicsfilter" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->start_scaler_mode = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"statusbar" ) ) {
      settings->statusbar = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"separation" ) ) {
      settings->stereo_ay = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"beeperstereo" ) ) {
      settings->stereo_beeper = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"svgamode" ) ) {
      settings->svga_mode = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"tapefile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->tape_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"tapetraps" ) ) {
      settings->tape_traps = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"trdosdisk" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->trdosdisk_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"writableroms" ) ) {
      settings->writable_roms = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxatasp" ) ) {
      settings->zxatasp_active = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxataspmasterfile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->zxatasp_master_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxataspslavefile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->zxatasp_slave_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxataspupload" ) ) {
      settings->zxatasp_upload = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxataspwriteprotect" ) ) {
      settings->zxatasp_wp = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxcf" ) ) {
      settings->zxcf_active = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxcfcffile" ) ) {
      string = xmlNodeListGetString( doc, node->xmlChildrenNode, 1 );
      settings->zxcf_pri_file = string ? strdup( string ) : NULL;
    } else
    if( !strcmp( node->name, (const xmlChar*)"zxcfupload" ) ) {
      settings->zxcf_upload = atoi( xmlNodeListGetString( doc, node->xmlChildrenNode, 1 ) );
    } else
#line 254"settings.pl"
    if( !strcmp( node->name, (const xmlChar*)"text" ) ) {
      /* Do nothing */
    } else {
      ui_error( UI_ERROR_WARNING, "Unknown setting '%s' in config file",
		node->name );
    }

    node = node->next;
  }

  return 0;
}

int
settings_write_config( settings_info *settings )
{
  const char *home; char path[256], buffer[80]; 

  xmlDocPtr doc; xmlNodePtr root;

  home = utils_get_home_path(); if( !home ) return 1;

  snprintf( path, 256, "%s/%s", home, CONFIG_FILE_NAME );

  /* Create the XML document */
  doc = xmlNewDoc( "1.0" );

  root = xmlNewNode( NULL, "settings" );
  xmlDocSetRootElement( doc, root );
  xmlNewTextChild( root, NULL, "aspecthint", settings->aspect_hint ? "1" : "0" );
  xmlNewTextChild( root, NULL, "autoload", settings->auto_load ? "1" : "0" );
  xmlNewTextChild( root, NULL, "autosavesettings", settings->autosave_settings ? "1" : "0" );
  xmlNewTextChild( root, NULL, "bwtv", settings->bw_tv ? "1" : "0" );
  if( settings->competition_code ) {
    snprintf( buffer, 80, "%d", settings->competition_code );
    xmlNewTextChild( root, NULL, "competitioncode", buffer );
  }
  xmlNewTextChild( root, NULL, "competitionmode", settings->competition_mode ? "1" : "0" );
  xmlNewTextChild( root, NULL, "confirmactions", settings->confirm_actions ? "1" : "0" );
  if( settings->dck_file )
    xmlNewTextChild( root, NULL, "dock", settings->dck_file );
  xmlNewTextChild( root, NULL, "embedsnapshot", settings->embed_snapshot ? "1" : "0" );
  if( settings->emulation_speed ) {
    snprintf( buffer, 80, "%d", settings->emulation_speed );
    xmlNewTextChild( root, NULL, "speed", buffer );
  }
  if( settings->frame_rate ) {
    snprintf( buffer, 80, "%d", settings->frame_rate );
    xmlNewTextChild( root, NULL, "rate", buffer );
  }
  xmlNewTextChild( root, NULL, "fullscreen", settings->full_screen ? "1" : "0" );
  if( settings->if2_file )
    xmlNewTextChild( root, NULL, "if2cart", settings->if2_file );
  xmlNewTextChild( root, NULL, "interface2", settings->interface2 ? "1" : "0" );
  xmlNewTextChild( root, NULL, "issue2", settings->issue2 ? "1" : "0" );
  xmlNewTextChild( root, NULL, "kempston", settings->joy_kempston ? "1" : "0" );
  if( settings->joystick_1 )
    xmlNewTextChild( root, NULL, "joystick1", settings->joystick_1 );
  if( settings->joystick_1_fire_1 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_1 );
    xmlNewTextChild( root, NULL, "joystick1fire1", buffer );
  }
  if( settings->joystick_1_fire_10 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_10 );
    xmlNewTextChild( root, NULL, "joystick1fire10", buffer );
  }
  if( settings->joystick_1_fire_2 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_2 );
    xmlNewTextChild( root, NULL, "joystick1fire2", buffer );
  }
  if( settings->joystick_1_fire_3 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_3 );
    xmlNewTextChild( root, NULL, "joystick1fire3", buffer );
  }
  if( settings->joystick_1_fire_4 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_4 );
    xmlNewTextChild( root, NULL, "joystick1fire4", buffer );
  }
  if( settings->joystick_1_fire_5 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_5 );
    xmlNewTextChild( root, NULL, "joystick1fire5", buffer );
  }
  if( settings->joystick_1_fire_6 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_6 );
    xmlNewTextChild( root, NULL, "joystick1fire6", buffer );
  }
  if( settings->joystick_1_fire_7 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_7 );
    xmlNewTextChild( root, NULL, "joystick1fire7", buffer );
  }
  if( settings->joystick_1_fire_8 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_8 );
    xmlNewTextChild( root, NULL, "joystick1fire8", buffer );
  }
  if( settings->joystick_1_fire_9 ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_fire_9 );
    xmlNewTextChild( root, NULL, "joystick1fire9", buffer );
  }
  if( settings->joystick_1_output ) {
    snprintf( buffer, 80, "%d", settings->joystick_1_output );
    xmlNewTextChild( root, NULL, "joystick1output", buffer );
  }
  if( settings->joystick_2 )
    xmlNewTextChild( root, NULL, "joystick2", settings->joystick_2 );
  if( settings->joystick_2_fire_1 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_1 );
    xmlNewTextChild( root, NULL, "joystick2fire1", buffer );
  }
  if( settings->joystick_2_fire_10 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_10 );
    xmlNewTextChild( root, NULL, "joystick2fire10", buffer );
  }
  if( settings->joystick_2_fire_2 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_2 );
    xmlNewTextChild( root, NULL, "joystick2fire2", buffer );
  }
  if( settings->joystick_2_fire_3 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_3 );
    xmlNewTextChild( root, NULL, "joystick2fire3", buffer );
  }
  if( settings->joystick_2_fire_4 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_4 );
    xmlNewTextChild( root, NULL, "joystick2fire4", buffer );
  }
  if( settings->joystick_2_fire_5 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_5 );
    xmlNewTextChild( root, NULL, "joystick2fire5", buffer );
  }
  if( settings->joystick_2_fire_6 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_6 );
    xmlNewTextChild( root, NULL, "joystick2fire6", buffer );
  }
  if( settings->joystick_2_fire_7 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_7 );
    xmlNewTextChild( root, NULL, "joystick2fire7", buffer );
  }
  if( settings->joystick_2_fire_8 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_8 );
    xmlNewTextChild( root, NULL, "joystick2fire8", buffer );
  }
  if( settings->joystick_2_fire_9 ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_fire_9 );
    xmlNewTextChild( root, NULL, "joystick2fire9", buffer );
  }
  if( settings->joystick_2_output ) {
    snprintf( buffer, 80, "%d", settings->joystick_2_output );
    xmlNewTextChild( root, NULL, "joystick2output", buffer );
  }
  if( settings->joystick_keyboard_output ) {
    snprintf( buffer, 80, "%d", settings->joystick_keyboard_output );
    xmlNewTextChild( root, NULL, "joystickkeyboardoutput", buffer );
  }
  if( settings->playback_file )
    xmlNewTextChild( root, NULL, "playbackfile", settings->playback_file );
  if( settings->plus3disk_file )
    xmlNewTextChild( root, NULL, "plus3disk", settings->plus3disk_file );
  xmlNewTextChild( root, NULL, "printer", settings->printer ? "1" : "0" );
  if( settings->printer_graphics_filename )
    xmlNewTextChild( root, NULL, "graphicsfile", settings->printer_graphics_filename );
  if( settings->printer_text_filename )
    xmlNewTextChild( root, NULL, "textfile", settings->printer_text_filename );
  if( settings->record_file )
    xmlNewTextChild( root, NULL, "recordfile", settings->record_file );
  if( settings->rom_128_0 )
    xmlNewTextChild( root, NULL, "rom1280", settings->rom_128_0 );
  if( settings->rom_128_1 )
    xmlNewTextChild( root, NULL, "rom1281", settings->rom_128_1 );
  if( settings->rom_16 )
    xmlNewTextChild( root, NULL, "rom16", settings->rom_16 );
  if( settings->rom_48 )
    xmlNewTextChild( root, NULL, "rom48", settings->rom_48 );
  if( settings->rom_pentagon_0 )
    xmlNewTextChild( root, NULL, "rompentagon0", settings->rom_pentagon_0 );
  if( settings->rom_pentagon_1 )
    xmlNewTextChild( root, NULL, "rompentagon1", settings->rom_pentagon_1 );
  if( settings->rom_pentagon_2 )
    xmlNewTextChild( root, NULL, "rompentagon2", settings->rom_pentagon_2 );
  if( settings->rom_plus2_0 )
    xmlNewTextChild( root, NULL, "romplus20", settings->rom_plus2_0 );
  if( settings->rom_plus2_1 )
    xmlNewTextChild( root, NULL, "romplus21", settings->rom_plus2_1 );
  if( settings->rom_plus2a_0 )
    xmlNewTextChild( root, NULL, "romplus2a0", settings->rom_plus2a_0 );
  if( settings->rom_plus2a_1 )
    xmlNewTextChild( root, NULL, "romplus2a1", settings->rom_plus2a_1 );
  if( settings->rom_plus2a_2 )
    xmlNewTextChild( root, NULL, "romplus2a2", settings->rom_plus2a_2 );
  if( settings->rom_plus2a_3 )
    xmlNewTextChild( root, NULL, "romplus2a3", settings->rom_plus2a_3 );
  if( settings->rom_plus3_0 )
    xmlNewTextChild( root, NULL, "romplus30", settings->rom_plus3_0 );
  if( settings->rom_plus3_1 )
    xmlNewTextChild( root, NULL, "romplus31", settings->rom_plus3_1 );
  if( settings->rom_plus3_2 )
    xmlNewTextChild( root, NULL, "romplus32", settings->rom_plus3_2 );
  if( settings->rom_plus3_3 )
    xmlNewTextChild( root, NULL, "romplus33", settings->rom_plus3_3 );
  if( settings->rom_plus3e_0 )
    xmlNewTextChild( root, NULL, "romplus3e0", settings->rom_plus3e_0 );
  if( settings->rom_plus3e_1 )
    xmlNewTextChild( root, NULL, "romplus3e1", settings->rom_plus3e_1 );
  if( settings->rom_plus3e_2 )
    xmlNewTextChild( root, NULL, "romplus3e2", settings->rom_plus3e_2 );
  if( settings->rom_plus3e_3 )
    xmlNewTextChild( root, NULL, "romplus3e3", settings->rom_plus3e_3 );
  if( settings->rom_scorpion_0 )
    xmlNewTextChild( root, NULL, "romscorpion0", settings->rom_scorpion_0 );
  if( settings->rom_scorpion_1 )
    xmlNewTextChild( root, NULL, "romscorpion1", settings->rom_scorpion_1 );
  if( settings->rom_scorpion_2 )
    xmlNewTextChild( root, NULL, "romscorpion2", settings->rom_scorpion_2 );
  if( settings->rom_scorpion_3 )
    xmlNewTextChild( root, NULL, "romscorpion3", settings->rom_scorpion_3 );
  if( settings->rom_spec_se_0 )
    xmlNewTextChild( root, NULL, "romspecse0", settings->rom_spec_se_0 );
  if( settings->rom_spec_se_1 )
    xmlNewTextChild( root, NULL, "romspecse1", settings->rom_spec_se_1 );
  if( settings->rom_tc2048 )
    xmlNewTextChild( root, NULL, "romtc2048", settings->rom_tc2048 );
  if( settings->rom_tc2068_0 )
    xmlNewTextChild( root, NULL, "romtc20680", settings->rom_tc2068_0 );
  if( settings->rom_tc2068_1 )
    xmlNewTextChild( root, NULL, "romtc20681", settings->rom_tc2068_1 );
  xmlNewTextChild( root, NULL, "compressrzx", settings->rzx_compression ? "1" : "0" );
  xmlNewTextChild( root, NULL, "simpleide", settings->simpleide_active ? "1" : "0" );
  if( settings->simpleide_master_file )
    xmlNewTextChild( root, NULL, "simpleidemasterfile", settings->simpleide_master_file );
  if( settings->simpleide_slave_file )
    xmlNewTextChild( root, NULL, "simpleideslavefile", settings->simpleide_slave_file );
  xmlNewTextChild( root, NULL, "slttraps", settings->slt_traps ? "1" : "0" );
  xmlNewTextChild( root, NULL, "snapsasz80", settings->snaps_as_z80 ? "1" : "0" );
  if( settings->snapshot )
    xmlNewTextChild( root, NULL, "snapshot", settings->snapshot );
  xmlNewTextChild( root, NULL, "sound", settings->sound ? "1" : "0" );
  if( settings->sound_device )
    xmlNewTextChild( root, NULL, "sounddevice", settings->sound_device );
  xmlNewTextChild( root, NULL, "soundforce8bit", settings->sound_force_8bit ? "1" : "0" );
  xmlNewTextChild( root, NULL, "loadingsound", settings->sound_load ? "1" : "0" );
  if( settings->start_machine )
    xmlNewTextChild( root, NULL, "machine", settings->start_machine );
  if( settings->start_scaler_mode )
    xmlNewTextChild( root, NULL, "graphicsfilter", settings->start_scaler_mode );
  xmlNewTextChild( root, NULL, "statusbar", settings->statusbar ? "1" : "0" );
  xmlNewTextChild( root, NULL, "separation", settings->stereo_ay ? "1" : "0" );
  xmlNewTextChild( root, NULL, "beeperstereo", settings->stereo_beeper ? "1" : "0" );
  if( settings->svga_mode ) {
    snprintf( buffer, 80, "%d", settings->svga_mode );
    xmlNewTextChild( root, NULL, "svgamode", buffer );
  }
  if( settings->tape_file )
    xmlNewTextChild( root, NULL, "tapefile", settings->tape_file );
  xmlNewTextChild( root, NULL, "tapetraps", settings->tape_traps ? "1" : "0" );
  if( settings->trdosdisk_file )
    xmlNewTextChild( root, NULL, "trdosdisk", settings->trdosdisk_file );
  xmlNewTextChild( root, NULL, "writableroms", settings->writable_roms ? "1" : "0" );
  xmlNewTextChild( root, NULL, "zxatasp", settings->zxatasp_active ? "1" : "0" );
  if( settings->zxatasp_master_file )
    xmlNewTextChild( root, NULL, "zxataspmasterfile", settings->zxatasp_master_file );
  if( settings->zxatasp_slave_file )
    xmlNewTextChild( root, NULL, "zxataspslavefile", settings->zxatasp_slave_file );
  xmlNewTextChild( root, NULL, "zxataspupload", settings->zxatasp_upload ? "1" : "0" );
  xmlNewTextChild( root, NULL, "zxataspwriteprotect", settings->zxatasp_wp ? "1" : "0" );
  xmlNewTextChild( root, NULL, "zxcf", settings->zxcf_active ? "1" : "0" );
  if( settings->zxcf_pri_file )
    xmlNewTextChild( root, NULL, "zxcfcffile", settings->zxcf_pri_file );
  xmlNewTextChild( root, NULL, "zxcfupload", settings->zxcf_upload ? "1" : "0" );
#line 313"settings.pl"

  xmlSaveFormatFile( path, doc, 1 );

  return 0;
}

#endif				/* #ifdef HAVE_LIB_XML2 */

/* Read options from the command line */
static int
settings_command_line( settings_info *settings, int *first_arg,
                       int argc, char **argv )
{

  struct option long_options[] = {

    {    "aspect-hint", 0, &(settings->aspect_hint), 1 },
    { "no-aspect-hint", 0, &(settings->aspect_hint), 0 },
    {    "auto-load", 0, &(settings->auto_load), 1 },
    { "no-auto-load", 0, &(settings->auto_load), 0 },
    {    "autosave-settings", 0, &(settings->autosave_settings), 1 },
    { "no-autosave-settings", 0, &(settings->autosave_settings), 0 },
    {    "bw-tv", 0, &(settings->bw_tv), 1 },
    { "no-bw-tv", 0, &(settings->bw_tv), 0 },
    { "competition-code", 1, NULL, 256 },
    {    "competition-mode", 0, &(settings->competition_mode), 1 },
    { "no-competition-mode", 0, &(settings->competition_mode), 0 },
    {    "confirm-actions", 0, &(settings->confirm_actions), 1 },
    { "no-confirm-actions", 0, &(settings->confirm_actions), 0 },
    { "dock", 1, NULL, 257 },
    {    "embed-snapshot", 0, &(settings->embed_snapshot), 1 },
    { "no-embed-snapshot", 0, &(settings->embed_snapshot), 0 },
    { "speed", 1, NULL, 259 },
    { "rate", 1, NULL, 260 },
    {    "full-screen", 0, &(settings->full_screen), 1 },
    { "no-full-screen", 0, &(settings->full_screen), 0 },
    { "if2cart", 1, NULL, 261 },
    {    "interface2", 0, &(settings->interface2), 1 },
    { "no-interface2", 0, &(settings->interface2), 0 },
    {    "issue2", 0, &(settings->issue2), 1 },
    { "no-issue2", 0, &(settings->issue2), 0 },
    {    "kempston", 0, &(settings->joy_kempston), 1 },
    { "no-kempston", 0, &(settings->joy_kempston), 0 },
    { "joystick-1", 1, NULL, 'j' },
    { "joystick-1-fire-1", 1, NULL, 262 },
    { "joystick-1-fire-10", 1, NULL, 263 },
    { "joystick-1-fire-2", 1, NULL, 264 },
    { "joystick-1-fire-3", 1, NULL, 265 },
    { "joystick-1-fire-4", 1, NULL, 266 },
    { "joystick-1-fire-5", 1, NULL, 267 },
    { "joystick-1-fire-6", 1, NULL, 268 },
    { "joystick-1-fire-7", 1, NULL, 269 },
    { "joystick-1-fire-8", 1, NULL, 270 },
    { "joystick-1-fire-9", 1, NULL, 271 },
    { "joystick-1-output", 1, NULL, 272 },
    { "joystick-2", 1, NULL, 273 },
    { "joystick-2-fire-1", 1, NULL, 274 },
    { "joystick-2-fire-10", 1, NULL, 275 },
    { "joystick-2-fire-2", 1, NULL, 276 },
    { "joystick-2-fire-3", 1, NULL, 277 },
    { "joystick-2-fire-4", 1, NULL, 278 },
    { "joystick-2-fire-5", 1, NULL, 279 },
    { "joystick-2-fire-6", 1, NULL, 280 },
    { "joystick-2-fire-7", 1, NULL, 281 },
    { "joystick-2-fire-8", 1, NULL, 282 },
    { "joystick-2-fire-9", 1, NULL, 283 },
    { "joystick-2-output", 1, NULL, 284 },
    { "joystick-keyboard-output", 1, NULL, 285 },
    { "playback", 1, NULL, 'p' },
    { "plus3disk", 1, NULL, 286 },
    {    "printer", 0, &(settings->printer), 1 },
    { "no-printer", 0, &(settings->printer), 0 },
    { "graphicsfile", 1, NULL, 287 },
    { "textfile", 1, NULL, 288 },
    { "record", 1, NULL, 'r' },
    { "rom-128-0", 1, NULL, 289 },
    { "rom-128-1", 1, NULL, 290 },
    { "rom-16", 1, NULL, 291 },
    { "rom-48", 1, NULL, 292 },
    { "rom-pentagon-0", 1, NULL, 293 },
    { "rom-pentagon-1", 1, NULL, 294 },
    { "rom-pentagon-2", 1, NULL, 295 },
    { "rom-plus2-0", 1, NULL, 296 },
    { "rom-plus2-1", 1, NULL, 297 },
    { "rom-plus2a-0", 1, NULL, 298 },
    { "rom-plus2a-1", 1, NULL, 299 },
    { "rom-plus2a-2", 1, NULL, 300 },
    { "rom-plus2a-3", 1, NULL, 301 },
    { "rom-plus3-0", 1, NULL, 302 },
    { "rom-plus3-1", 1, NULL, 303 },
    { "rom-plus3-2", 1, NULL, 304 },
    { "rom-plus3-3", 1, NULL, 305 },
    { "rom-plus3e-0", 1, NULL, 306 },
    { "rom-plus3e-1", 1, NULL, 307 },
    { "rom-plus3e-2", 1, NULL, 308 },
    { "rom-plus3e-3", 1, NULL, 309 },
    { "rom-scorpion-0", 1, NULL, 310 },
    { "rom-scorpion-1", 1, NULL, 311 },
    { "rom-scorpion-2", 1, NULL, 312 },
    { "rom-scorpion-3", 1, NULL, 313 },
    { "rom-spec-se-0", 1, NULL, 314 },
    { "rom-spec-se-1", 1, NULL, 315 },
    { "rom-tc2048", 1, NULL, 316 },
    { "rom-tc2068-0", 1, NULL, 317 },
    { "rom-tc2068-1", 1, NULL, 318 },
    {    "compress-rzx", 0, &(settings->rzx_compression), 1 },
    { "no-compress-rzx", 0, &(settings->rzx_compression), 0 },
    {    "simpleide", 0, &(settings->simpleide_active), 1 },
    { "no-simpleide", 0, &(settings->simpleide_active), 0 },
    { "simpleide-masterfile", 1, NULL, 319 },
    { "simpleide-slavefile", 1, NULL, 320 },
    {    "slt", 0, &(settings->slt_traps), 1 },
    { "no-slt", 0, &(settings->slt_traps), 0 },
    {    "snaps-as-z80", 0, &(settings->snaps_as_z80), 1 },
    { "no-snaps-as-z80", 0, &(settings->snaps_as_z80), 0 },
    { "snapshot", 1, NULL, 's' },
    {    "sound", 0, &(settings->sound), 1 },
    { "no-sound", 0, &(settings->sound), 0 },
    { "sound-device", 1, NULL, 'd' },
    {    "sound-force-8bit", 0, &(settings->sound_force_8bit), 1 },
    { "no-sound-force-8bit", 0, &(settings->sound_force_8bit), 0 },
    {    "loading-sound", 0, &(settings->sound_load), 1 },
    { "no-loading-sound", 0, &(settings->sound_load), 0 },
    { "machine", 1, NULL, 'm' },
    { "graphics-filter", 1, NULL, 'g' },
    {    "statusbar", 0, &(settings->statusbar), 1 },
    { "no-statusbar", 0, &(settings->statusbar), 0 },
    {    "separation", 0, &(settings->stereo_ay), 1 },
    { "no-separation", 0, &(settings->stereo_ay), 0 },
    {    "beeper-stereo", 0, &(settings->stereo_beeper), 1 },
    { "no-beeper-stereo", 0, &(settings->stereo_beeper), 0 },
    { "svgamode", 1, NULL, 'v' },
    { "tape", 1, NULL, 't' },
    {    "traps", 0, &(settings->tape_traps), 1 },
    { "no-traps", 0, &(settings->tape_traps), 0 },
    { "trdosdisk", 1, NULL, 321 },
    {    "writable-roms", 0, &(settings->writable_roms), 1 },
    { "no-writable-roms", 0, &(settings->writable_roms), 0 },
    {    "zxatasp", 0, &(settings->zxatasp_active), 1 },
    { "no-zxatasp", 0, &(settings->zxatasp_active), 0 },
    { "zxatasp-masterfile", 1, NULL, 322 },
    { "zxatasp-slavefile", 1, NULL, 323 },
    {    "zxatasp-upload", 0, &(settings->zxatasp_upload), 1 },
    { "no-zxatasp-upload", 0, &(settings->zxatasp_upload), 0 },
    {    "zxatasp-write-protect", 0, &(settings->zxatasp_wp), 1 },
    { "no-zxatasp-write-protect", 0, &(settings->zxatasp_wp), 0 },
    {    "zxcf", 0, &(settings->zxcf_active), 1 },
    { "no-zxcf", 0, &(settings->zxcf_active), 0 },
    { "zxcf-cffile", 1, NULL, 324 },
    {    "zxcf-upload", 0, &(settings->zxcf_upload), 1 },
    { "no-zxcf-upload", 0, &(settings->zxcf_upload), 0 },
#line 358"settings.pl"

    { "help", 0, NULL, 'h' },
    { "version", 0, NULL, 'V' },

    { 0, 0, 0, 0 }		/* End marker: DO NOT REMOVE */
  };

  while( 1 ) {

    int c;

    c = getopt_long( argc, argv, "d:hm:o:p:r:s:t:v:g:V", long_options, NULL );

    if( c == -1 ) break;	/* End of option list */

    switch( c ) {

    case 0: break;	/* Used for long option returns */

    case 256: settings->competition_code = atoi( optarg ); break;
    case 257: settings_set_string( &settings->dck_file, optarg ); break;
    case 259: settings->emulation_speed = atoi( optarg ); break;
    case 260: settings->frame_rate = atoi( optarg ); break;
    case 261: settings_set_string( &settings->if2_file, optarg ); break;
    case 'j': settings_set_string( &settings->joystick_1, optarg ); break;
    case 262: settings->joystick_1_fire_1 = atoi( optarg ); break;
    case 263: settings->joystick_1_fire_10 = atoi( optarg ); break;
    case 264: settings->joystick_1_fire_2 = atoi( optarg ); break;
    case 265: settings->joystick_1_fire_3 = atoi( optarg ); break;
    case 266: settings->joystick_1_fire_4 = atoi( optarg ); break;
    case 267: settings->joystick_1_fire_5 = atoi( optarg ); break;
    case 268: settings->joystick_1_fire_6 = atoi( optarg ); break;
    case 269: settings->joystick_1_fire_7 = atoi( optarg ); break;
    case 270: settings->joystick_1_fire_8 = atoi( optarg ); break;
    case 271: settings->joystick_1_fire_9 = atoi( optarg ); break;
    case 272: settings->joystick_1_output = atoi( optarg ); break;
    case 273: settings_set_string( &settings->joystick_2, optarg ); break;
    case 274: settings->joystick_2_fire_1 = atoi( optarg ); break;
    case 275: settings->joystick_2_fire_10 = atoi( optarg ); break;
    case 276: settings->joystick_2_fire_2 = atoi( optarg ); break;
    case 277: settings->joystick_2_fire_3 = atoi( optarg ); break;
    case 278: settings->joystick_2_fire_4 = atoi( optarg ); break;
    case 279: settings->joystick_2_fire_5 = atoi( optarg ); break;
    case 280: settings->joystick_2_fire_6 = atoi( optarg ); break;
    case 281: settings->joystick_2_fire_7 = atoi( optarg ); break;
    case 282: settings->joystick_2_fire_8 = atoi( optarg ); break;
    case 283: settings->joystick_2_fire_9 = atoi( optarg ); break;
    case 284: settings->joystick_2_output = atoi( optarg ); break;
    case 285: settings->joystick_keyboard_output = atoi( optarg ); break;
    case 'p': settings_set_string( &settings->playback_file, optarg ); break;
    case 286: settings_set_string( &settings->plus3disk_file, optarg ); break;
    case 287: settings_set_string( &settings->printer_graphics_filename, optarg ); break;
    case 288: settings_set_string( &settings->printer_text_filename, optarg ); break;
    case 'r': settings_set_string( &settings->record_file, optarg ); break;
    case 289: settings_set_string( &settings->rom_128_0, optarg ); break;
    case 290: settings_set_string( &settings->rom_128_1, optarg ); break;
    case 291: settings_set_string( &settings->rom_16, optarg ); break;
    case 292: settings_set_string( &settings->rom_48, optarg ); break;
    case 293: settings_set_string( &settings->rom_pentagon_0, optarg ); break;
    case 294: settings_set_string( &settings->rom_pentagon_1, optarg ); break;
    case 295: settings_set_string( &settings->rom_pentagon_2, optarg ); break;
    case 296: settings_set_string( &settings->rom_plus2_0, optarg ); break;
    case 297: settings_set_string( &settings->rom_plus2_1, optarg ); break;
    case 298: settings_set_string( &settings->rom_plus2a_0, optarg ); break;
    case 299: settings_set_string( &settings->rom_plus2a_1, optarg ); break;
    case 300: settings_set_string( &settings->rom_plus2a_2, optarg ); break;
    case 301: settings_set_string( &settings->rom_plus2a_3, optarg ); break;
    case 302: settings_set_string( &settings->rom_plus3_0, optarg ); break;
    case 303: settings_set_string( &settings->rom_plus3_1, optarg ); break;
    case 304: settings_set_string( &settings->rom_plus3_2, optarg ); break;
    case 305: settings_set_string( &settings->rom_plus3_3, optarg ); break;
    case 306: settings_set_string( &settings->rom_plus3e_0, optarg ); break;
    case 307: settings_set_string( &settings->rom_plus3e_1, optarg ); break;
    case 308: settings_set_string( &settings->rom_plus3e_2, optarg ); break;
    case 309: settings_set_string( &settings->rom_plus3e_3, optarg ); break;
    case 310: settings_set_string( &settings->rom_scorpion_0, optarg ); break;
    case 311: settings_set_string( &settings->rom_scorpion_1, optarg ); break;
    case 312: settings_set_string( &settings->rom_scorpion_2, optarg ); break;
    case 313: settings_set_string( &settings->rom_scorpion_3, optarg ); break;
    case 314: settings_set_string( &settings->rom_spec_se_0, optarg ); break;
    case 315: settings_set_string( &settings->rom_spec_se_1, optarg ); break;
    case 316: settings_set_string( &settings->rom_tc2048, optarg ); break;
    case 317: settings_set_string( &settings->rom_tc2068_0, optarg ); break;
    case 318: settings_set_string( &settings->rom_tc2068_1, optarg ); break;
    case 319: settings_set_string( &settings->simpleide_master_file, optarg ); break;
    case 320: settings_set_string( &settings->simpleide_slave_file, optarg ); break;
    case 's': settings_set_string( &settings->snapshot, optarg ); break;
    case 'd': settings_set_string( &settings->sound_device, optarg ); break;
    case 'm': settings_set_string( &settings->start_machine, optarg ); break;
    case 'g': settings_set_string( &settings->start_scaler_mode, optarg ); break;
    case 'v': settings->svga_mode = atoi( optarg ); break;
    case 't': settings_set_string( &settings->tape_file, optarg ); break;
    case 321: settings_set_string( &settings->trdosdisk_file, optarg ); break;
    case 322: settings_set_string( &settings->zxatasp_master_file, optarg ); break;
    case 323: settings_set_string( &settings->zxatasp_slave_file, optarg ); break;
    case 324: settings_set_string( &settings->zxcf_pri_file, optarg ); break;
#line 402"settings.pl"

    case 'h': settings->show_help = 1; break;
    case 'V': settings->show_version = 1; break;

    case ':':
    case '?':
      break;

    default:
      fprintf( stderr, "%s: getopt_long returned `%c'\n",
	       fuse_progname, (char)c );
      break;

    }
  }

  /* Store the location of the first non-option argument */
  *first_arg = optind;

  return 0;
}

/* Copy one settings object to another */
int settings_copy( settings_info *dest, settings_info *src )
{
  if( settings_defaults( dest ) ) return 1;
  free( dest->start_machine ); dest->start_machine = NULL;
  free( dest->start_scaler_mode ); dest->start_scaler_mode = NULL;

  dest->aspect_hint = src->aspect_hint;
  dest->auto_load = src->auto_load;
  dest->autosave_settings = src->autosave_settings;
  dest->bw_tv = src->bw_tv;
  dest->competition_code = src->competition_code;
  dest->competition_mode = src->competition_mode;
  dest->confirm_actions = src->confirm_actions;
  if( src->dck_file ) {
    dest->dck_file = strdup( src->dck_file );
    if( !dest->dck_file ) { settings_free( dest ); return 1; }
  }
  dest->embed_snapshot = src->embed_snapshot;
  dest->emulation_speed = src->emulation_speed;
  dest->frame_rate = src->frame_rate;
  dest->full_screen = src->full_screen;
  if( src->if2_file ) {
    dest->if2_file = strdup( src->if2_file );
    if( !dest->if2_file ) { settings_free( dest ); return 1; }
  }
  dest->interface2 = src->interface2;
  dest->issue2 = src->issue2;
  dest->joy_kempston = src->joy_kempston;
  if( src->joystick_1 ) {
    dest->joystick_1 = strdup( src->joystick_1 );
    if( !dest->joystick_1 ) { settings_free( dest ); return 1; }
  }
  dest->joystick_1_fire_1 = src->joystick_1_fire_1;
  dest->joystick_1_fire_10 = src->joystick_1_fire_10;
  dest->joystick_1_fire_2 = src->joystick_1_fire_2;
  dest->joystick_1_fire_3 = src->joystick_1_fire_3;
  dest->joystick_1_fire_4 = src->joystick_1_fire_4;
  dest->joystick_1_fire_5 = src->joystick_1_fire_5;
  dest->joystick_1_fire_6 = src->joystick_1_fire_6;
  dest->joystick_1_fire_7 = src->joystick_1_fire_7;
  dest->joystick_1_fire_8 = src->joystick_1_fire_8;
  dest->joystick_1_fire_9 = src->joystick_1_fire_9;
  dest->joystick_1_output = src->joystick_1_output;
  if( src->joystick_2 ) {
    dest->joystick_2 = strdup( src->joystick_2 );
    if( !dest->joystick_2 ) { settings_free( dest ); return 1; }
  }
  dest->joystick_2_fire_1 = src->joystick_2_fire_1;
  dest->joystick_2_fire_10 = src->joystick_2_fire_10;
  dest->joystick_2_fire_2 = src->joystick_2_fire_2;
  dest->joystick_2_fire_3 = src->joystick_2_fire_3;
  dest->joystick_2_fire_4 = src->joystick_2_fire_4;
  dest->joystick_2_fire_5 = src->joystick_2_fire_5;
  dest->joystick_2_fire_6 = src->joystick_2_fire_6;
  dest->joystick_2_fire_7 = src->joystick_2_fire_7;
  dest->joystick_2_fire_8 = src->joystick_2_fire_8;
  dest->joystick_2_fire_9 = src->joystick_2_fire_9;
  dest->joystick_2_output = src->joystick_2_output;
  dest->joystick_keyboard_output = src->joystick_keyboard_output;
  if( src->playback_file ) {
    dest->playback_file = strdup( src->playback_file );
    if( !dest->playback_file ) { settings_free( dest ); return 1; }
  }
  if( src->plus3disk_file ) {
    dest->plus3disk_file = strdup( src->plus3disk_file );
    if( !dest->plus3disk_file ) { settings_free( dest ); return 1; }
  }
  dest->printer = src->printer;
  if( src->printer_graphics_filename ) {
    dest->printer_graphics_filename = strdup( src->printer_graphics_filename );
    if( !dest->printer_graphics_filename ) { settings_free( dest ); return 1; }
  }
  if( src->printer_text_filename ) {
    dest->printer_text_filename = strdup( src->printer_text_filename );
    if( !dest->printer_text_filename ) { settings_free( dest ); return 1; }
  }
  if( src->record_file ) {
    dest->record_file = strdup( src->record_file );
    if( !dest->record_file ) { settings_free( dest ); return 1; }
  }
  if( src->rom_128_0 ) {
    dest->rom_128_0 = strdup( src->rom_128_0 );
    if( !dest->rom_128_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_128_1 ) {
    dest->rom_128_1 = strdup( src->rom_128_1 );
    if( !dest->rom_128_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_16 ) {
    dest->rom_16 = strdup( src->rom_16 );
    if( !dest->rom_16 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_48 ) {
    dest->rom_48 = strdup( src->rom_48 );
    if( !dest->rom_48 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_pentagon_0 ) {
    dest->rom_pentagon_0 = strdup( src->rom_pentagon_0 );
    if( !dest->rom_pentagon_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_pentagon_1 ) {
    dest->rom_pentagon_1 = strdup( src->rom_pentagon_1 );
    if( !dest->rom_pentagon_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_pentagon_2 ) {
    dest->rom_pentagon_2 = strdup( src->rom_pentagon_2 );
    if( !dest->rom_pentagon_2 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus2_0 ) {
    dest->rom_plus2_0 = strdup( src->rom_plus2_0 );
    if( !dest->rom_plus2_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus2_1 ) {
    dest->rom_plus2_1 = strdup( src->rom_plus2_1 );
    if( !dest->rom_plus2_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus2a_0 ) {
    dest->rom_plus2a_0 = strdup( src->rom_plus2a_0 );
    if( !dest->rom_plus2a_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus2a_1 ) {
    dest->rom_plus2a_1 = strdup( src->rom_plus2a_1 );
    if( !dest->rom_plus2a_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus2a_2 ) {
    dest->rom_plus2a_2 = strdup( src->rom_plus2a_2 );
    if( !dest->rom_plus2a_2 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus2a_3 ) {
    dest->rom_plus2a_3 = strdup( src->rom_plus2a_3 );
    if( !dest->rom_plus2a_3 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3_0 ) {
    dest->rom_plus3_0 = strdup( src->rom_plus3_0 );
    if( !dest->rom_plus3_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3_1 ) {
    dest->rom_plus3_1 = strdup( src->rom_plus3_1 );
    if( !dest->rom_plus3_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3_2 ) {
    dest->rom_plus3_2 = strdup( src->rom_plus3_2 );
    if( !dest->rom_plus3_2 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3_3 ) {
    dest->rom_plus3_3 = strdup( src->rom_plus3_3 );
    if( !dest->rom_plus3_3 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3e_0 ) {
    dest->rom_plus3e_0 = strdup( src->rom_plus3e_0 );
    if( !dest->rom_plus3e_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3e_1 ) {
    dest->rom_plus3e_1 = strdup( src->rom_plus3e_1 );
    if( !dest->rom_plus3e_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3e_2 ) {
    dest->rom_plus3e_2 = strdup( src->rom_plus3e_2 );
    if( !dest->rom_plus3e_2 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_plus3e_3 ) {
    dest->rom_plus3e_3 = strdup( src->rom_plus3e_3 );
    if( !dest->rom_plus3e_3 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_scorpion_0 ) {
    dest->rom_scorpion_0 = strdup( src->rom_scorpion_0 );
    if( !dest->rom_scorpion_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_scorpion_1 ) {
    dest->rom_scorpion_1 = strdup( src->rom_scorpion_1 );
    if( !dest->rom_scorpion_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_scorpion_2 ) {
    dest->rom_scorpion_2 = strdup( src->rom_scorpion_2 );
    if( !dest->rom_scorpion_2 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_scorpion_3 ) {
    dest->rom_scorpion_3 = strdup( src->rom_scorpion_3 );
    if( !dest->rom_scorpion_3 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_spec_se_0 ) {
    dest->rom_spec_se_0 = strdup( src->rom_spec_se_0 );
    if( !dest->rom_spec_se_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_spec_se_1 ) {
    dest->rom_spec_se_1 = strdup( src->rom_spec_se_1 );
    if( !dest->rom_spec_se_1 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_tc2048 ) {
    dest->rom_tc2048 = strdup( src->rom_tc2048 );
    if( !dest->rom_tc2048 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_tc2068_0 ) {
    dest->rom_tc2068_0 = strdup( src->rom_tc2068_0 );
    if( !dest->rom_tc2068_0 ) { settings_free( dest ); return 1; }
  }
  if( src->rom_tc2068_1 ) {
    dest->rom_tc2068_1 = strdup( src->rom_tc2068_1 );
    if( !dest->rom_tc2068_1 ) { settings_free( dest ); return 1; }
  }
  dest->rzx_compression = src->rzx_compression;
  dest->simpleide_active = src->simpleide_active;
  if( src->simpleide_master_file ) {
    dest->simpleide_master_file = strdup( src->simpleide_master_file );
    if( !dest->simpleide_master_file ) { settings_free( dest ); return 1; }
  }
  if( src->simpleide_slave_file ) {
    dest->simpleide_slave_file = strdup( src->simpleide_slave_file );
    if( !dest->simpleide_slave_file ) { settings_free( dest ); return 1; }
  }
  dest->slt_traps = src->slt_traps;
  dest->snaps_as_z80 = src->snaps_as_z80;
  if( src->snapshot ) {
    dest->snapshot = strdup( src->snapshot );
    if( !dest->snapshot ) { settings_free( dest ); return 1; }
  }
  dest->sound = src->sound;
  if( src->sound_device ) {
    dest->sound_device = strdup( src->sound_device );
    if( !dest->sound_device ) { settings_free( dest ); return 1; }
  }
  dest->sound_force_8bit = src->sound_force_8bit;
  dest->sound_load = src->sound_load;
  if( src->start_machine ) {
    dest->start_machine = strdup( src->start_machine );
    if( !dest->start_machine ) { settings_free( dest ); return 1; }
  }
  if( src->start_scaler_mode ) {
    dest->start_scaler_mode = strdup( src->start_scaler_mode );
    if( !dest->start_scaler_mode ) { settings_free( dest ); return 1; }
  }
  dest->statusbar = src->statusbar;
  dest->stereo_ay = src->stereo_ay;
  dest->stereo_beeper = src->stereo_beeper;
  dest->svga_mode = src->svga_mode;
  if( src->tape_file ) {
    dest->tape_file = strdup( src->tape_file );
    if( !dest->tape_file ) { settings_free( dest ); return 1; }
  }
  dest->tape_traps = src->tape_traps;
  if( src->trdosdisk_file ) {
    dest->trdosdisk_file = strdup( src->trdosdisk_file );
    if( !dest->trdosdisk_file ) { settings_free( dest ); return 1; }
  }
  dest->writable_roms = src->writable_roms;
  dest->zxatasp_active = src->zxatasp_active;
  if( src->zxatasp_master_file ) {
    dest->zxatasp_master_file = strdup( src->zxatasp_master_file );
    if( !dest->zxatasp_master_file ) { settings_free( dest ); return 1; }
  }
  if( src->zxatasp_slave_file ) {
    dest->zxatasp_slave_file = strdup( src->zxatasp_slave_file );
    if( !dest->zxatasp_slave_file ) { settings_free( dest ); return 1; }
  }
  dest->zxatasp_upload = src->zxatasp_upload;
  dest->zxatasp_wp = src->zxatasp_wp;
  dest->zxcf_active = src->zxcf_active;
  if( src->zxcf_pri_file ) {
    dest->zxcf_pri_file = strdup( src->zxcf_pri_file );
    if( !dest->zxcf_pri_file ) { settings_free( dest ); return 1; }
  }
  dest->zxcf_upload = src->zxcf_upload;
#line 450"settings.pl"

  return 0;
}

char **
settings_get_rom_setting( settings_info *settings, size_t which )
{
  switch( which ) {
  case  0: return &( settings->rom_16       );
  case  1: return &( settings->rom_48       );
  case  2: return &( settings->rom_128_0    );
  case  3: return &( settings->rom_128_1    );
  case  4: return &( settings->rom_plus2_0  );
  case  5: return &( settings->rom_plus2_1  );
  case  6: return &( settings->rom_plus2a_0 );
  case  7: return &( settings->rom_plus2a_1 );
  case  8: return &( settings->rom_plus2a_2 );
  case  9: return &( settings->rom_plus2a_3 );
  case 10: return &( settings->rom_plus3_0  );
  case 11: return &( settings->rom_plus3_1  );
  case 12: return &( settings->rom_plus3_2  );
  case 13: return &( settings->rom_plus3_3  );
  case 14: return &( settings->rom_tc2048   );
  case 15: return &( settings->rom_tc2068_0 );
  case 16: return &( settings->rom_tc2068_1 );
  case 17: return &( settings->rom_pentagon_0 );
  case 18: return &( settings->rom_pentagon_1 );
  case 19: return &( settings->rom_pentagon_2 );
  case 20: return &( settings->rom_scorpion_0 );
  case 21: return &( settings->rom_scorpion_1 );
  case 22: return &( settings->rom_scorpion_2 );
  case 23: return &( settings->rom_scorpion_3 );
  case 24: return &( settings->rom_plus3e_0 );
  case 25: return &( settings->rom_plus3e_1 );
  case 26: return &( settings->rom_plus3e_2 );
  case 27: return &( settings->rom_plus3e_3 );
  case 28: return &( settings->rom_spec_se_0 );
  case 29: return &( settings->rom_spec_se_1 );
  default: return NULL;
  }
}

int
settings_set_string( char **string_setting, const char *value )
{
  /* No need to do anything if the two strings are in fact the
     same pointer */
  if( *string_setting == value ) return 0;

  if( *string_setting) free( *string_setting );
  *string_setting = strdup( value );
  if( !( *string_setting ) ) {
    ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ );
    return 1;
  }

  return 0;
}

int
settings_free( settings_info *settings )
{
  if( settings->dck_file ) free( settings->dck_file );
  if( settings->if2_file ) free( settings->if2_file );
  if( settings->joystick_1 ) free( settings->joystick_1 );
  if( settings->joystick_2 ) free( settings->joystick_2 );
  if( settings->playback_file ) free( settings->playback_file );
  if( settings->plus3disk_file ) free( settings->plus3disk_file );
  if( settings->printer_graphics_filename ) free( settings->printer_graphics_filename );
  if( settings->printer_text_filename ) free( settings->printer_text_filename );
  if( settings->record_file ) free( settings->record_file );
  if( settings->rom_128_0 ) free( settings->rom_128_0 );
  if( settings->rom_128_1 ) free( settings->rom_128_1 );
  if( settings->rom_16 ) free( settings->rom_16 );
  if( settings->rom_48 ) free( settings->rom_48 );
  if( settings->rom_pentagon_0 ) free( settings->rom_pentagon_0 );
  if( settings->rom_pentagon_1 ) free( settings->rom_pentagon_1 );
  if( settings->rom_pentagon_2 ) free( settings->rom_pentagon_2 );
  if( settings->rom_plus2_0 ) free( settings->rom_plus2_0 );
  if( settings->rom_plus2_1 ) free( settings->rom_plus2_1 );
  if( settings->rom_plus2a_0 ) free( settings->rom_plus2a_0 );
  if( settings->rom_plus2a_1 ) free( settings->rom_plus2a_1 );
  if( settings->rom_plus2a_2 ) free( settings->rom_plus2a_2 );
  if( settings->rom_plus2a_3 ) free( settings->rom_plus2a_3 );
  if( settings->rom_plus3_0 ) free( settings->rom_plus3_0 );
  if( settings->rom_plus3_1 ) free( settings->rom_plus3_1 );
  if( settings->rom_plus3_2 ) free( settings->rom_plus3_2 );
  if( settings->rom_plus3_3 ) free( settings->rom_plus3_3 );
  if( settings->rom_plus3e_0 ) free( settings->rom_plus3e_0 );
  if( settings->rom_plus3e_1 ) free( settings->rom_plus3e_1 );
  if( settings->rom_plus3e_2 ) free( settings->rom_plus3e_2 );
  if( settings->rom_plus3e_3 ) free( settings->rom_plus3e_3 );
  if( settings->rom_scorpion_0 ) free( settings->rom_scorpion_0 );
  if( settings->rom_scorpion_1 ) free( settings->rom_scorpion_1 );
  if( settings->rom_scorpion_2 ) free( settings->rom_scorpion_2 );
  if( settings->rom_scorpion_3 ) free( settings->rom_scorpion_3 );
  if( settings->rom_spec_se_0 ) free( settings->rom_spec_se_0 );
  if( settings->rom_spec_se_1 ) free( settings->rom_spec_se_1 );
  if( settings->rom_tc2048 ) free( settings->rom_tc2048 );
  if( settings->rom_tc2068_0 ) free( settings->rom_tc2068_0 );
  if( settings->rom_tc2068_1 ) free( settings->rom_tc2068_1 );
  if( settings->simpleide_master_file ) free( settings->simpleide_master_file );
  if( settings->simpleide_slave_file ) free( settings->simpleide_slave_file );
  if( settings->snapshot ) free( settings->snapshot );
  if( settings->sound_device ) free( settings->sound_device );
  if( settings->start_machine ) free( settings->start_machine );
  if( settings->start_scaler_mode ) free( settings->start_scaler_mode );
  if( settings->tape_file ) free( settings->tape_file );
  if( settings->trdosdisk_file ) free( settings->trdosdisk_file );
  if( settings->zxatasp_master_file ) free( settings->zxatasp_master_file );
  if( settings->zxatasp_slave_file ) free( settings->zxatasp_slave_file );
  if( settings->zxcf_pri_file ) free( settings->zxcf_pri_file );
#line 521"settings.pl"

  return 0;
}

int
settings_end( void )
{
#ifdef HAVE_LIB_XML2
  if( settings_current.autosave_settings )
    settings_write_config( &settings_current );
#endif			/* #ifdef HAVE_LIB_XML2 */

  settings_free( &settings_current );

  return 0;
}
