/* options.c: options dialog boxes
   Copyright (c) 2001-2013 Philip Kendall, Marek Januszewski, Stuart Brady

   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.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

   Author contact information:

   E-mail: philip-fuse@shadowmagic.org.uk

*/

/* This file is autogenerated from options.dat by options.pl.
   Do not edit unless you know what you're doing! */

#include "config.h"

#ifdef UI_WIN32                /* Use this file if we're using WIN32 */

#include "libspectrum.h"

#include "display.h"
#include "fuse.h"
#include "menu.h"
#include "options.h"
#include "options_internals.h"
#include "periph.h"
#include "settings.h"
#include "ui/win32/win32internals.h"
#include "utils.h"

static int
option_enumerate_combo( const char * const *options, char *value, int count,
                        int def ) {
  int i;
  if( value != NULL ) {
    for( i = 0; i < count; i++) {
      if( !strcmp( value, options[ i ] ) )
        return i;
    }
  }
  return def;
}

static void
menu_options_general_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_EMULATION_SPEED, EM_LIMITTEXT,
                      5, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.emulation_speed );
  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_EMULATION_SPEED, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_FRAME_RATE, EM_LIMITTEXT,
                      1, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.frame_rate );
  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_FRAME_RATE, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_ISSUE2, BM_SETCHECK,
    settings_current.issue2 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_RECREATED_SPECTRUM, BM_SETCHECK,
    settings_current.recreated_spectrum ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_KEYBOARD_ARROWS_SHIFTED, BM_SETCHECK,
    settings_current.keyboard_arrows_shifted ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_WRITABLE_ROMS, BM_SETCHECK,
    settings_current.writable_roms ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_LATE_TIMINGS, BM_SETCHECK,
    settings_current.late_timings ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_Z80_IS_CMOS, BM_SETCHECK,
    settings_current.z80_is_cmos ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_RS232_HANDSHAKE, BM_SETCHECK,
    settings_current.rs232_handshake ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_BW_TV, BM_SETCHECK,
    settings_current.bw_tv ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_FULL_SCREEN, BM_SETCHECK,
    settings_current.full_screen ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_STATUSBAR, BM_SETCHECK,
    settings_current.statusbar ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_JOY_PROMPT, BM_SETCHECK,
    settings_current.joy_prompt ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_CONFIRM_ACTIONS, BM_SETCHECK,
    settings_current.confirm_actions ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_AUTOSAVE_SETTINGS, BM_SETCHECK,
    settings_current.autosave_settings ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_general_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_EMULATION_SPEED, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.emulation_speed = atoi( buffer );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_GENERAL_FRAME_RATE, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.frame_rate = atoi( buffer );

  settings_current.issue2 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_ISSUE2 );

  settings_current.recreated_spectrum =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_RECREATED_SPECTRUM );

  settings_current.keyboard_arrows_shifted =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_KEYBOARD_ARROWS_SHIFTED );

  settings_current.writable_roms =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_WRITABLE_ROMS );

  settings_current.late_timings =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_LATE_TIMINGS );

  settings_current.z80_is_cmos =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_Z80_IS_CMOS );

  settings_current.rs232_handshake =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_RS232_HANDSHAKE );

  settings_current.bw_tv =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_BW_TV );

  settings_current.full_screen =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_FULL_SCREEN );

  settings_current.statusbar =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_STATUSBAR );

  settings_current.joy_prompt =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_JOY_PROMPT );

  settings_current.confirm_actions =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_CONFIRM_ACTIONS );

  settings_current.autosave_settings =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_GENERAL_AUTOSAVE_SETTINGS );

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_general_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_general_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_general_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_general( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_GENERAL ),
             fuse_hWnd, (DLGPROC) menu_options_general_proc );

  fuse_emulation_unpause();
}


static const char * const media_phantom_typist_mode_combo[] = {
  "Auto",
  "Keyword",
  "Keystroke",
  "Menu",
  "Plus 2A",
  "Plus 3",
};

static const int media_phantom_typist_mode_combo_count = 6;

int
option_enumerate_media_phantom_typist_mode( void ) {
  return option_enumerate_combo( media_phantom_typist_mode_combo,
                                 settings_current.phantom_typist_mode,
                                 media_phantom_typist_mode_combo_count,
                                 0 );
}

static void
menu_options_media_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_AUTO_LOAD, BM_SETCHECK,
    settings_current.auto_load ? BST_CHECKED : BST_UNCHECKED, 0 );

  for( i = 0; i < media_phantom_typist_mode_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_PHANTOM_TYPIST_MODE, CB_ADDSTRING,
                        0, (LPARAM) media_phantom_typist_mode_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_PHANTOM_TYPIST_MODE, CB_SETCURSEL,
                      (LPARAM) 0, 0 );
  if( settings_current.phantom_typist_mode != NULL ) {
    for( i = 0; i < media_phantom_typist_mode_combo_count; i++ ) {
      if( !strcmp( settings_current.phantom_typist_mode,
                   media_phantom_typist_mode_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_PHANTOM_TYPIST_MODE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_DETECT_LOADER, BM_SETCHECK,
    settings_current.detect_loader ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_FASTLOAD, BM_SETCHECK,
    settings_current.fastload ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_TAPE_TRAPS, BM_SETCHECK,
    settings_current.tape_traps ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_ACCELERATE_LOADER, BM_SETCHECK,
    settings_current.accelerate_loader ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_SLT_TRAPS, BM_SETCHECK,
    settings_current.slt_traps ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_MDR_LEN, EM_LIMITTEXT,
                      3, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.mdr_len );
  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_MDR_LEN, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_MDR_RANDOM_LEN, BM_SETCHECK,
    settings_current.mdr_random_len ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_media_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  settings_current.auto_load =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_AUTO_LOAD );

  libspectrum_free( settings_current.phantom_typist_mode );
  settings_current.phantom_typist_mode =
    utils_safe_strdup( media_phantom_typist_mode_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_PHANTOM_TYPIST_MODE, CB_GETCURSEL, 0, 0 ) ] );

  settings_current.detect_loader =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_DETECT_LOADER );

  settings_current.fastload =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_FASTLOAD );

  settings_current.tape_traps =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_TAPE_TRAPS );

  settings_current.accelerate_loader =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_ACCELERATE_LOADER );

  settings_current.slt_traps =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_SLT_TRAPS );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_MEDIA_MDR_LEN, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.mdr_len = atoi( buffer );

  settings_current.mdr_random_len =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MEDIA_MDR_RANDOM_LEN );

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_media_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_media_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_media_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_media( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_MEDIA ),
             fuse_hWnd, (DLGPROC) menu_options_media_proc );

  fuse_emulation_unpause();
}

static void
menu_options_peripherals_general_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_JOY_KEMPSTON, BM_SETCHECK,
    settings_current.joy_kempston ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_KEMPSTON_MOUSE, BM_SETCHECK,
    settings_current.kempston_mouse ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MOUSE_SWAP_BUTTONS, BM_SETCHECK,
    settings_current.mouse_swap_buttons ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_INTERFACE1, BM_SETCHECK,
    settings_current.interface1 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_INTERFACE2, BM_SETCHECK,
    settings_current.interface2 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE1, BM_SETCHECK,
    settings_current.multiface1 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE128, BM_SETCHECK,
    settings_current.multiface128 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE3, BM_SETCHECK,
    settings_current.multiface3 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE1_STEALTH, BM_SETCHECK,
    settings_current.multiface1_stealth ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_PRINTER, BM_SETCHECK,
    settings_current.printer ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_ZXPRINTER, BM_SETCHECK,
    settings_current.zxprinter ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_SPECCYBOOT, BM_SETCHECK,
    settings_current.speccyboot ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_SPECTRANET, BM_SETCHECK,
    settings_current.spectranet ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_SPECTRANET_DISABLE, BM_SETCHECK,
    settings_current.spectranet_disable ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_TTX2000S, BM_SETCHECK,
    settings_current.ttx2000s ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_USOURCE, BM_SETCHECK,
    settings_current.usource ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_peripherals_general_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  /* Get a copy of current settings */
  settings_info original_settings;
  memset( &original_settings, 0, sizeof( settings_info ) );
  settings_copy( &original_settings, &settings_current );

  settings_current.joy_kempston =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_JOY_KEMPSTON );

  settings_current.kempston_mouse =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_KEMPSTON_MOUSE );

  settings_current.mouse_swap_buttons =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MOUSE_SWAP_BUTTONS );

  settings_current.interface1 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_INTERFACE1 );

  settings_current.interface2 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_INTERFACE2 );

  settings_current.multiface1 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE1 );

  settings_current.multiface128 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE128 );

  settings_current.multiface3 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE3 );

  settings_current.multiface1_stealth =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_MULTIFACE1_STEALTH );

  settings_current.printer =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_PRINTER );

  settings_current.zxprinter =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_ZXPRINTER );

  settings_current.speccyboot =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_SPECCYBOOT );

  settings_current.spectranet =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_SPECTRANET );

  settings_current.spectranet_disable =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_SPECTRANET_DISABLE );

  settings_current.ttx2000s =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_TTX2000S );

  settings_current.usource =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_GENERAL_USOURCE );

  int needs_hard_reset = periph_postcheck();

  /* Confirm reset */
  if( needs_hard_reset ) {
    ShowWindow( hwndDlg, SW_HIDE );

    if( !win32ui_confirm("Some options need to reset the machine. Reset?" ) ) {
      /* Cancel new settings */
      settings_copy( &settings_current, &original_settings );
      settings_free( &original_settings );

      ShowWindow( hwndDlg, SW_SHOW );
      return;
    }
  }

  settings_free( &original_settings );

  periph_posthook();

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_peripherals_general_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_peripherals_general_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_peripherals_general_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_peripherals_general( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_PERIPHERALS_GENERAL ),
             fuse_hWnd, (DLGPROC) menu_options_peripherals_general_proc );

  fuse_emulation_unpause();
}

static void
menu_options_peripherals_sound_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_FULLER, BM_SETCHECK,
    settings_current.fuller ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_MELODIK, BM_SETCHECK,
    settings_current.melodik ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_SPECDRUM, BM_SETCHECK,
    settings_current.specdrum ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_COVOX, BM_SETCHECK,
    settings_current.covox ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_USPEECH, BM_SETCHECK,
    settings_current.uspeech ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_peripherals_sound_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  /* Get a copy of current settings */
  settings_info original_settings;
  memset( &original_settings, 0, sizeof( settings_info ) );
  settings_copy( &original_settings, &settings_current );

  settings_current.fuller =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_FULLER );

  settings_current.melodik =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_MELODIK );

  settings_current.specdrum =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_SPECDRUM );

  settings_current.covox =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_COVOX );

  settings_current.uspeech =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_SOUND_USPEECH );

  int needs_hard_reset = periph_postcheck();

  /* Confirm reset */
  if( needs_hard_reset ) {
    ShowWindow( hwndDlg, SW_HIDE );

    if( !win32ui_confirm("Some options need to reset the machine. Reset?" ) ) {
      /* Cancel new settings */
      settings_copy( &settings_current, &original_settings );
      settings_free( &original_settings );

      ShowWindow( hwndDlg, SW_SHOW );
      return;
    }
  }

  settings_free( &original_settings );

  periph_posthook();

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_peripherals_sound_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_peripherals_sound_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_peripherals_sound_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_peripherals_sound( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_PERIPHERALS_SOUND ),
             fuse_hWnd, (DLGPROC) menu_options_peripherals_sound_proc );

  fuse_emulation_unpause();
}

static void
menu_options_peripherals_disk_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_SIMPLEIDE_ACTIVE, BM_SETCHECK,
    settings_current.simpleide_active ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXATASP_ACTIVE, BM_SETCHECK,
    settings_current.zxatasp_active ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXATASP_UPLOAD, BM_SETCHECK,
    settings_current.zxatasp_upload ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXATASP_WP, BM_SETCHECK,
    settings_current.zxatasp_wp ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXCF_ACTIVE, BM_SETCHECK,
    settings_current.zxcf_active ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXCF_UPLOAD, BM_SETCHECK,
    settings_current.zxcf_upload ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVIDE_ENABLED, BM_SETCHECK,
    settings_current.divide_enabled ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVIDE_WP, BM_SETCHECK,
    settings_current.divide_wp ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVMMC_ENABLED, BM_SETCHECK,
    settings_current.divmmc_enabled ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVMMC_WP, BM_SETCHECK,
    settings_current.divmmc_wp ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_PLUSD, BM_SETCHECK,
    settings_current.plusd ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIDAKTIK80, BM_SETCHECK,
    settings_current.didaktik80 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DISCIPLE, BM_SETCHECK,
    settings_current.disciple ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_BETA128, BM_SETCHECK,
    settings_current.beta128 ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_BETA128_48BOOT, BM_SETCHECK,
    settings_current.beta128_48boot ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_OPUS, BM_SETCHECK,
    settings_current.opus ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXMMC_ENABLED, BM_SETCHECK,
    settings_current.zxmmc_enabled ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_peripherals_disk_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  /* Get a copy of current settings */
  settings_info original_settings;
  memset( &original_settings, 0, sizeof( settings_info ) );
  settings_copy( &original_settings, &settings_current );

  settings_current.simpleide_active =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_SIMPLEIDE_ACTIVE );

  settings_current.zxatasp_active =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXATASP_ACTIVE );

  settings_current.zxatasp_upload =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXATASP_UPLOAD );

  settings_current.zxatasp_wp =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXATASP_WP );

  settings_current.zxcf_active =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXCF_ACTIVE );

  settings_current.zxcf_upload =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXCF_UPLOAD );

  settings_current.divide_enabled =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVIDE_ENABLED );

  settings_current.divide_wp =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVIDE_WP );

  settings_current.divmmc_enabled =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVMMC_ENABLED );

  settings_current.divmmc_wp =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIVMMC_WP );

  settings_current.plusd =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_PLUSD );

  settings_current.didaktik80 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DIDAKTIK80 );

  settings_current.disciple =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_DISCIPLE );

  settings_current.beta128 =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_BETA128 );

  settings_current.beta128_48boot =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_BETA128_48BOOT );

  settings_current.opus =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_OPUS );

  settings_current.zxmmc_enabled =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_PERIPHERALS_DISK_ZXMMC_ENABLED );

  int needs_hard_reset = periph_postcheck();

  /* Confirm reset */
  if( needs_hard_reset ) {
    ShowWindow( hwndDlg, SW_HIDE );

    if( !win32ui_confirm("Some options need to reset the machine. Reset?" ) ) {
      /* Cancel new settings */
      settings_copy( &settings_current, &original_settings );
      settings_free( &original_settings );

      ShowWindow( hwndDlg, SW_SHOW );
      return;
    }
  }

  settings_free( &original_settings );

  periph_posthook();

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_peripherals_disk_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_peripherals_disk_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_peripherals_disk_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_peripherals_disk( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_PERIPHERALS_DISK ),
             fuse_hWnd, (DLGPROC) menu_options_peripherals_disk_proc );

  fuse_emulation_unpause();
}

static void
menu_options_rzx_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_RZX_AUTOSAVES, BM_SETCHECK,
    settings_current.rzx_autosaves ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_RZX_COMPRESSION, BM_SETCHECK,
    settings_current.rzx_compression ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_COMPETITION_MODE, BM_SETCHECK,
    settings_current.competition_mode ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_COMPETITION_CODE, EM_LIMITTEXT,
                      8, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.competition_code );
  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_COMPETITION_CODE, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_EMBED_SNAPSHOT, BM_SETCHECK,
    settings_current.embed_snapshot ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_rzx_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  settings_current.rzx_autosaves =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_RZX_RZX_AUTOSAVES );

  settings_current.rzx_compression =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_RZX_RZX_COMPRESSION );

  settings_current.competition_mode =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_RZX_COMPETITION_MODE );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_RZX_COMPETITION_CODE, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.competition_code = atoi( buffer );

  settings_current.embed_snapshot =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_RZX_EMBED_SNAPSHOT );

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_rzx_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_rzx_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_rzx_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_rzx( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_RZX ),
             fuse_hWnd, (DLGPROC) menu_options_rzx_proc );

  fuse_emulation_unpause();
}


static const char * const sound_stereo_ay_combo[] = {
  "None",
  "ACB",
  "ABC",
};

static const int sound_stereo_ay_combo_count = 3;

int
option_enumerate_sound_stereo_ay( void ) {
  return option_enumerate_combo( sound_stereo_ay_combo,
                                 settings_current.stereo_ay,
                                 sound_stereo_ay_combo_count,
                                 0 );
}


static const char * const sound_speaker_type_combo[] = {
  "TV speaker",
  "Beeper",
  "Unfiltered",
};

static const int sound_speaker_type_combo_count = 3;

int
option_enumerate_sound_speaker_type( void ) {
  return option_enumerate_combo( sound_speaker_type_combo,
                                 settings_current.speaker_type,
                                 sound_speaker_type_combo_count,
                                 0 );
}

static void
menu_options_sound_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SOUND, BM_SETCHECK,
    settings_current.sound ? BST_CHECKED : BST_UNCHECKED, 0 );

  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SOUND_LOAD, BM_SETCHECK,
    settings_current.sound_load ? BST_CHECKED : BST_UNCHECKED, 0 );

  for( i = 0; i < sound_stereo_ay_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_STEREO_AY, CB_ADDSTRING,
                        0, (LPARAM) sound_stereo_ay_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_STEREO_AY, CB_SETCURSEL,
                      (LPARAM) 0, 0 );
  if( settings_current.stereo_ay != NULL ) {
    for( i = 0; i < sound_stereo_ay_combo_count; i++ ) {
      if( !strcmp( settings_current.stereo_ay,
                   sound_stereo_ay_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_STEREO_AY,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SOUND_FORCE_8BIT, BM_SETCHECK,
    settings_current.sound_force_8bit ? BST_CHECKED : BST_UNCHECKED, 0 );

  for( i = 0; i < sound_speaker_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SPEAKER_TYPE, CB_ADDSTRING,
                        0, (LPARAM) sound_speaker_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SPEAKER_TYPE, CB_SETCURSEL,
                      (LPARAM) 0, 0 );
  if( settings_current.speaker_type != NULL ) {
    for( i = 0; i < sound_speaker_type_combo_count; i++ ) {
      if( !strcmp( settings_current.speaker_type,
                   sound_speaker_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SPEAKER_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_AY, EM_LIMITTEXT,
                      3, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.volume_ay );
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_AY, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_BEEPER, EM_LIMITTEXT,
                      3, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.volume_beeper );
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_BEEPER, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_SPECDRUM, EM_LIMITTEXT,
                      3, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.volume_specdrum );
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_SPECDRUM, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_COVOX, EM_LIMITTEXT,
                      3, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.volume_covox );
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_COVOX, WM_SETTEXT,
                      0, (LPARAM) buffer );

  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_USPEECH, EM_LIMITTEXT,
                      3, 0 );
  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  snprintf( buffer, 80, "%d", settings_current.volume_uspeech );
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_USPEECH, WM_SETTEXT,
                      0, (LPARAM) buffer );

}

static void
menu_options_sound_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  settings_current.sound =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_SOUND_SOUND );

  settings_current.sound_load =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_SOUND_SOUND_LOAD );

  libspectrum_free( settings_current.stereo_ay );
  settings_current.stereo_ay =
    utils_safe_strdup( sound_stereo_ay_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_STEREO_AY, CB_GETCURSEL, 0, 0 ) ] );

  settings_current.sound_force_8bit =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_SOUND_SOUND_FORCE_8BIT );

  libspectrum_free( settings_current.speaker_type );
  settings_current.speaker_type =
    utils_safe_strdup( sound_speaker_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_SPEAKER_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_AY, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.volume_ay = atoi( buffer );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_BEEPER, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.volume_beeper = atoi( buffer );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_SPECDRUM, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.volume_specdrum = atoi( buffer );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_COVOX, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.volume_covox = atoi( buffer );

  /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
  SendDlgItemMessage( hwndDlg, IDC_OPT_SOUND_VOLUME_USPEECH, WM_GETTEXT,
                      80, (LPARAM) buffer );
  settings_current.volume_uspeech = atoi( buffer );

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_sound_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_sound_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_sound_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_sound( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_SOUND ),
             fuse_hWnd, (DLGPROC) menu_options_sound_proc );

  fuse_emulation_unpause();
}


static const char * const diskoptions_drive_plus3a_type_combo[] = {
  "Single-sided 40 track",
  "Double-sided 40 track",
  "Single-sided 80 track",
  "Double-sided 80 track",
};

static const int diskoptions_drive_plus3a_type_combo_count = 4;

int
option_enumerate_diskoptions_drive_plus3a_type( void ) {
  return option_enumerate_combo( diskoptions_drive_plus3a_type_combo,
                                 settings_current.drive_plus3a_type,
                                 diskoptions_drive_plus3a_type_combo_count,
                                 0 );
}


static const char * const diskoptions_drive_plus3b_type_combo[] = {
  "Disabled",
  "Single-sided 40 track",
  "Double-sided 40 track",
  "Single-sided 80 track",
  "Double-sided 80 track",
};

static const int diskoptions_drive_plus3b_type_combo_count = 5;

int
option_enumerate_diskoptions_drive_plus3b_type( void ) {
  return option_enumerate_combo( diskoptions_drive_plus3b_type_combo,
                                 settings_current.drive_plus3b_type,
                                 diskoptions_drive_plus3b_type_combo_count,
                                 4 );
}

#define diskoptions_drive_beta128a_type_combo diskoptions_drive_plus3a_type_combo
#define diskoptions_drive_beta128a_type_combo_count diskoptions_drive_plus3a_type_combo_count

int
option_enumerate_diskoptions_drive_beta128a_type( void ) {
  return option_enumerate_combo( diskoptions_drive_beta128a_type_combo,
                                 settings_current.drive_beta128a_type,
                                 diskoptions_drive_beta128a_type_combo_count,
                                 3 );
}

#define diskoptions_drive_beta128b_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_beta128b_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_beta128b_type( void ) {
  return option_enumerate_combo( diskoptions_drive_beta128b_type_combo,
                                 settings_current.drive_beta128b_type,
                                 diskoptions_drive_beta128b_type_combo_count,
                                 4 );
}

#define diskoptions_drive_beta128c_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_beta128c_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_beta128c_type( void ) {
  return option_enumerate_combo( diskoptions_drive_beta128c_type_combo,
                                 settings_current.drive_beta128c_type,
                                 diskoptions_drive_beta128c_type_combo_count,
                                 4 );
}

#define diskoptions_drive_beta128d_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_beta128d_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_beta128d_type( void ) {
  return option_enumerate_combo( diskoptions_drive_beta128d_type_combo,
                                 settings_current.drive_beta128d_type,
                                 diskoptions_drive_beta128d_type_combo_count,
                                 4 );
}

#define diskoptions_drive_plusd1_type_combo diskoptions_drive_plus3a_type_combo
#define diskoptions_drive_plusd1_type_combo_count diskoptions_drive_plus3a_type_combo_count

int
option_enumerate_diskoptions_drive_plusd1_type( void ) {
  return option_enumerate_combo( diskoptions_drive_plusd1_type_combo,
                                 settings_current.drive_plusd1_type,
                                 diskoptions_drive_plusd1_type_combo_count,
                                 3 );
}

#define diskoptions_drive_plusd2_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_plusd2_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_plusd2_type( void ) {
  return option_enumerate_combo( diskoptions_drive_plusd2_type_combo,
                                 settings_current.drive_plusd2_type,
                                 diskoptions_drive_plusd2_type_combo_count,
                                 4 );
}

#define diskoptions_drive_didaktik80a_type_combo diskoptions_drive_plus3a_type_combo
#define diskoptions_drive_didaktik80a_type_combo_count diskoptions_drive_plus3a_type_combo_count

int
option_enumerate_diskoptions_drive_didaktik80a_type( void ) {
  return option_enumerate_combo( diskoptions_drive_didaktik80a_type_combo,
                                 settings_current.drive_didaktik80a_type,
                                 diskoptions_drive_didaktik80a_type_combo_count,
                                 3 );
}

#define diskoptions_drive_didaktik80b_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_didaktik80b_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_didaktik80b_type( void ) {
  return option_enumerate_combo( diskoptions_drive_didaktik80b_type_combo,
                                 settings_current.drive_didaktik80b_type,
                                 diskoptions_drive_didaktik80b_type_combo_count,
                                 4 );
}

#define diskoptions_drive_disciple1_type_combo diskoptions_drive_plus3a_type_combo
#define diskoptions_drive_disciple1_type_combo_count diskoptions_drive_plus3a_type_combo_count

int
option_enumerate_diskoptions_drive_disciple1_type( void ) {
  return option_enumerate_combo( diskoptions_drive_disciple1_type_combo,
                                 settings_current.drive_disciple1_type,
                                 diskoptions_drive_disciple1_type_combo_count,
                                 3 );
}

#define diskoptions_drive_disciple2_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_disciple2_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_disciple2_type( void ) {
  return option_enumerate_combo( diskoptions_drive_disciple2_type_combo,
                                 settings_current.drive_disciple2_type,
                                 diskoptions_drive_disciple2_type_combo_count,
                                 4 );
}

#define diskoptions_drive_opus1_type_combo diskoptions_drive_plus3a_type_combo
#define diskoptions_drive_opus1_type_combo_count diskoptions_drive_plus3a_type_combo_count

int
option_enumerate_diskoptions_drive_opus1_type( void ) {
  return option_enumerate_combo( diskoptions_drive_opus1_type_combo,
                                 settings_current.drive_opus1_type,
                                 diskoptions_drive_opus1_type_combo_count,
                                 0 );
}

#define diskoptions_drive_opus2_type_combo diskoptions_drive_plus3b_type_combo
#define diskoptions_drive_opus2_type_combo_count diskoptions_drive_plus3b_type_combo_count

int
option_enumerate_diskoptions_drive_opus2_type( void ) {
  return option_enumerate_combo( diskoptions_drive_opus2_type_combo,
                                 settings_current.drive_opus2_type,
                                 diskoptions_drive_opus2_type_combo_count,
                                 1 );
}


static const char * const diskoptions_disk_try_merge_combo[] = {
  "Never",
  "With single-sided drives",
  "Always",
};

static const int diskoptions_disk_try_merge_combo_count = 3;

int
option_enumerate_diskoptions_disk_try_merge( void ) {
  return option_enumerate_combo( diskoptions_disk_try_merge_combo,
                                 settings_current.disk_try_merge,
                                 diskoptions_disk_try_merge_combo_count,
                                 1 );
}

static void
menu_options_diskoptions_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  for( i = 0; i < diskoptions_drive_plus3a_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3A_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_plus3a_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3A_TYPE, CB_SETCURSEL,
                      (LPARAM) 0, 0 );
  if( settings_current.drive_plus3a_type != NULL ) {
    for( i = 0; i < diskoptions_drive_plus3a_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_plus3a_type,
                   diskoptions_drive_plus3a_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3A_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_plus3b_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3B_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_plus3b_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3B_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_plus3b_type != NULL ) {
    for( i = 0; i < diskoptions_drive_plus3b_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_plus3b_type,
                   diskoptions_drive_plus3b_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3B_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_PLUS3_DETECT_SPEEDLOCK, BM_SETCHECK,
    settings_current.plus3_detect_speedlock ? BST_CHECKED : BST_UNCHECKED, 0 );

  for( i = 0; i < diskoptions_drive_beta128a_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128A_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_beta128a_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128A_TYPE, CB_SETCURSEL,
                      (LPARAM) 3, 0 );
  if( settings_current.drive_beta128a_type != NULL ) {
    for( i = 0; i < diskoptions_drive_beta128a_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_beta128a_type,
                   diskoptions_drive_beta128a_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128A_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_beta128b_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128B_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_beta128b_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128B_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_beta128b_type != NULL ) {
    for( i = 0; i < diskoptions_drive_beta128b_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_beta128b_type,
                   diskoptions_drive_beta128b_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128B_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_beta128c_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128C_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_beta128c_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128C_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_beta128c_type != NULL ) {
    for( i = 0; i < diskoptions_drive_beta128c_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_beta128c_type,
                   diskoptions_drive_beta128c_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128C_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_beta128d_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128D_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_beta128d_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128D_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_beta128d_type != NULL ) {
    for( i = 0; i < diskoptions_drive_beta128d_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_beta128d_type,
                   diskoptions_drive_beta128d_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128D_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_plusd1_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD1_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_plusd1_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD1_TYPE, CB_SETCURSEL,
                      (LPARAM) 3, 0 );
  if( settings_current.drive_plusd1_type != NULL ) {
    for( i = 0; i < diskoptions_drive_plusd1_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_plusd1_type,
                   diskoptions_drive_plusd1_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD1_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_plusd2_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD2_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_plusd2_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD2_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_plusd2_type != NULL ) {
    for( i = 0; i < diskoptions_drive_plusd2_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_plusd2_type,
                   diskoptions_drive_plusd2_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD2_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_didaktik80a_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80A_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_didaktik80a_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80A_TYPE, CB_SETCURSEL,
                      (LPARAM) 3, 0 );
  if( settings_current.drive_didaktik80a_type != NULL ) {
    for( i = 0; i < diskoptions_drive_didaktik80a_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_didaktik80a_type,
                   diskoptions_drive_didaktik80a_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80A_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_didaktik80b_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80B_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_didaktik80b_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80B_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_didaktik80b_type != NULL ) {
    for( i = 0; i < diskoptions_drive_didaktik80b_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_didaktik80b_type,
                   diskoptions_drive_didaktik80b_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80B_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_disciple1_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE1_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_disciple1_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE1_TYPE, CB_SETCURSEL,
                      (LPARAM) 3, 0 );
  if( settings_current.drive_disciple1_type != NULL ) {
    for( i = 0; i < diskoptions_drive_disciple1_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_disciple1_type,
                   diskoptions_drive_disciple1_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE1_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_disciple2_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE2_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_disciple2_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE2_TYPE, CB_SETCURSEL,
                      (LPARAM) 4, 0 );
  if( settings_current.drive_disciple2_type != NULL ) {
    for( i = 0; i < diskoptions_drive_disciple2_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_disciple2_type,
                   diskoptions_drive_disciple2_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE2_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_opus1_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS1_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_opus1_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS1_TYPE, CB_SETCURSEL,
                      (LPARAM) 0, 0 );
  if( settings_current.drive_opus1_type != NULL ) {
    for( i = 0; i < diskoptions_drive_opus1_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_opus1_type,
                   diskoptions_drive_opus1_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS1_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_drive_opus2_type_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS2_TYPE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_drive_opus2_type_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS2_TYPE, CB_SETCURSEL,
                      (LPARAM) 1, 0 );
  if( settings_current.drive_opus2_type != NULL ) {
    for( i = 0; i < diskoptions_drive_opus2_type_combo_count; i++ ) {
      if( !strcmp( settings_current.drive_opus2_type,
                   diskoptions_drive_opus2_type_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS2_TYPE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  for( i = 0; i < diskoptions_disk_try_merge_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DISK_TRY_MERGE, CB_ADDSTRING,
                        0, (LPARAM) diskoptions_disk_try_merge_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DISK_TRY_MERGE, CB_SETCURSEL,
                      (LPARAM) 1, 0 );
  if( settings_current.disk_try_merge != NULL ) {
    for( i = 0; i < diskoptions_disk_try_merge_combo_count; i++ ) {
      if( !strcmp( settings_current.disk_try_merge,
                   diskoptions_disk_try_merge_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DISK_TRY_MERGE,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DISK_ASK_MERGE, BM_SETCHECK,
    settings_current.disk_ask_merge ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_diskoptions_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  libspectrum_free( settings_current.drive_plus3a_type );
  settings_current.drive_plus3a_type =
    utils_safe_strdup( diskoptions_drive_plus3a_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3A_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_plus3b_type );
  settings_current.drive_plus3b_type =
    utils_safe_strdup( diskoptions_drive_plus3b_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUS3B_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  settings_current.plus3_detect_speedlock =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_DISKOPTIONS_PLUS3_DETECT_SPEEDLOCK );

  libspectrum_free( settings_current.drive_beta128a_type );
  settings_current.drive_beta128a_type =
    utils_safe_strdup( diskoptions_drive_beta128a_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128A_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_beta128b_type );
  settings_current.drive_beta128b_type =
    utils_safe_strdup( diskoptions_drive_beta128b_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128B_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_beta128c_type );
  settings_current.drive_beta128c_type =
    utils_safe_strdup( diskoptions_drive_beta128c_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128C_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_beta128d_type );
  settings_current.drive_beta128d_type =
    utils_safe_strdup( diskoptions_drive_beta128d_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_BETA128D_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_plusd1_type );
  settings_current.drive_plusd1_type =
    utils_safe_strdup( diskoptions_drive_plusd1_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD1_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_plusd2_type );
  settings_current.drive_plusd2_type =
    utils_safe_strdup( diskoptions_drive_plusd2_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_PLUSD2_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_didaktik80a_type );
  settings_current.drive_didaktik80a_type =
    utils_safe_strdup( diskoptions_drive_didaktik80a_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80A_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_didaktik80b_type );
  settings_current.drive_didaktik80b_type =
    utils_safe_strdup( diskoptions_drive_didaktik80b_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DIDAKTIK80B_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_disciple1_type );
  settings_current.drive_disciple1_type =
    utils_safe_strdup( diskoptions_drive_disciple1_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE1_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_disciple2_type );
  settings_current.drive_disciple2_type =
    utils_safe_strdup( diskoptions_drive_disciple2_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_DISCIPLE2_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_opus1_type );
  settings_current.drive_opus1_type =
    utils_safe_strdup( diskoptions_drive_opus1_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS1_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.drive_opus2_type );
  settings_current.drive_opus2_type =
    utils_safe_strdup( diskoptions_drive_opus2_type_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DRIVE_OPUS2_TYPE, CB_GETCURSEL, 0, 0 ) ] );

  libspectrum_free( settings_current.disk_try_merge );
  settings_current.disk_try_merge =
    utils_safe_strdup( diskoptions_disk_try_merge_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_DISKOPTIONS_DISK_TRY_MERGE, CB_GETCURSEL, 0, 0 ) ] );

  settings_current.disk_ask_merge =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_DISKOPTIONS_DISK_ASK_MERGE );

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_diskoptions_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_diskoptions_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_diskoptions_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_diskoptions( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_DISKOPTIONS ),
             fuse_hWnd, (DLGPROC) menu_options_diskoptions_proc );

  fuse_emulation_unpause();
}


static const char * const movie_movie_compr_combo[] = {
  "None",
  "Lossless",
  "High",
};

static const int movie_movie_compr_combo_count = 3;

int
option_enumerate_movie_movie_compr( void ) {
  return option_enumerate_combo( movie_movie_compr_combo,
                                 settings_current.movie_compr,
                                 movie_movie_compr_combo_count,
                                 1 );
}

static void
menu_options_movie_init( HWND hwndDlg )
{
  char buffer[80];
  int i;

  i = 0;
  buffer[0] = '\0';
  if( buffer[i] ) {};          /* Shut gcc up */

  for( i = 0; i < movie_movie_compr_combo_count; i++ ) {
    /* FIXME This is asuming SendDlgItemMessage is not UNICODE */
    SendDlgItemMessage( hwndDlg, IDC_OPT_MOVIE_MOVIE_COMPR, CB_ADDSTRING,
                        0, (LPARAM) movie_movie_compr_combo[i] );
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_MOVIE_MOVIE_COMPR, CB_SETCURSEL,
                      (LPARAM) 1, 0 );
  if( settings_current.movie_compr != NULL ) {
    for( i = 0; i < movie_movie_compr_combo_count; i++ ) {
      if( !strcmp( settings_current.movie_compr,
                   movie_movie_compr_combo[i] ) ) {
        SendDlgItemMessage( hwndDlg, IDC_OPT_MOVIE_MOVIE_COMPR,
                            CB_SETCURSEL, i, 0 );
      }
    }
  }
  SendDlgItemMessage( hwndDlg, IDC_OPT_MOVIE_MOVIE_STOP_AFTER_RZX, BM_SETCHECK,
    settings_current.movie_stop_after_rzx ? BST_CHECKED : BST_UNCHECKED, 0 );

}

static void
menu_options_movie_done( HWND hwndDlg )
{
  char buffer[80];

  buffer[0] = '\0';
  if( buffer[0] ) {};          /* Shut gcc up */

  libspectrum_free( settings_current.movie_compr );
  settings_current.movie_compr =
    utils_safe_strdup( movie_movie_compr_combo[
    SendDlgItemMessage( hwndDlg, IDC_OPT_MOVIE_MOVIE_COMPR, CB_GETCURSEL, 0, 0 ) ] );

  settings_current.movie_stop_after_rzx =
    IsDlgButtonChecked( hwndDlg, IDC_OPT_MOVIE_MOVIE_STOP_AFTER_RZX );

  win32statusbar_set_visibility( settings_current.statusbar );
  display_refresh_all();

  EndDialog( hwndDlg, 0 );
}

static BOOL CALLBACK
menu_options_movie_proc( HWND hwndDlg, UINT msg, WPARAM wParam GCC_UNUSED,
                              LPARAM lParam GCC_UNUSED )
{
  switch( msg )
  {
    case WM_INITDIALOG:
    {
      /* FIXME: save the handle returned by LoadIcon() in win32ui.c */
      SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
                   (LPARAM)LoadIcon( fuse_hInstance, "win32_icon" ) );

      /* initialize the controls with current settings */
      menu_options_movie_init( hwndDlg );

      return TRUE;
    }

    case WM_COMMAND:
      switch( LOWORD( wParam ) )
      {
        case IDOK:
          /* Read the controls and apply the settings */
          menu_options_movie_done( hwndDlg );
          return 0;

        case IDCANCEL:
          EndDialog( hwndDlg, 0 );
          return 0;
      }
      break;

    case WM_CLOSE:
      EndDialog( hwndDlg, 0 );
      return 0;
  }

  return FALSE;
}

void
menu_options_movie( int action GCC_UNUSED )
{
  fuse_emulation_pause();

  DialogBox( fuse_hInstance, MAKEINTRESOURCE( IDD_OPT_MOVIE ),
             fuse_hWnd, (DLGPROC) menu_options_movie_proc );

  fuse_emulation_unpause();
}


#endif                 /* #ifdef UI_WIN32 */

