/***************************************************************************

  M.A.M.E.32  -  Multiple Arcade Machine Emulator for Win32
  Win32 Portions Copyright (C) 1997-2001 Michael Soderstrom and Chris Kirmse

  This file is part of MAME32, and may only be used, modified and
  distributed under the terms of the MAME license, in "readme.txt".
  By continuing to use, modify or distribute this file you indicate
  that you have read the license and understand and accept it fully.

***************************************************************************/

/***************************************************************************

  Properties.c

    Properties Popup and Misc UI support routines.

    Created 8/29/98 by Mike Haaland (mhaaland@hypertech.com)

***************************************************************************/

#define MULTI_MONITOR

#include "driver.h"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <commctrl.h>
#include <commdlg.h>
#include <string.h>
#include <sys/stat.h>
#include <ddraw.h>
#include <htmlhelp.h>

#include "win32.h"
#include "info.h"
#include "config.h"
#include "fileio.h"
#include "Joystick.h"       /* For joystick avalibility.   */
#include "DIJoystick.h"     /* For DIJoystick avalibility. */
#include "DIKeyboard.h"     /* For DIKeyboard avalibility. */
#include "misc.h"
#include "tsv.h"
#include "directdraw.h"

#include "properties.h"
#include "audit32.h"
#include "DataMap.h"
#include "resource.h"
#include "help.h"
#include "M32Util.h"
#include "neogeo.h"

#ifdef _MSC_VER
#include "vc_prefix.h"
#endif /* _MSC_VER */

/*
   For compilers that don't support nameless unions
*/
#ifdef NONAMELESSUNION
/* PROPSHEETHEADER*/
#define nStartPage  DUMMYUNIONNAME2.nStartPage
/* PROPSHEETPAGE */
#define pszTemplate DUMMYUNIONNAME.pszTemplate
#define ppsp        DUMMYUNIONNAME3.ppsp
/* PROPSHEETHEADER */
#define pszIcon     DUMMYUNIONNAME.pszIcon
#endif

#define USE_SINGLELINE_TABCONTROL 0

/***************************************************************
 * Imported function prototypes
 ***************************************************************/

extern BOOL GameUsesTrackball(int game);
#ifdef ROMPATCH
extern BOOL GameUsesRomPatch(int game);
#endif
extern int load_driver_history(const struct GameDriver *drv, char *buffer, int bufsize);

/**************************************************************
 * Local function prototypes
 **************************************************************/

static INT_PTR CALLBACK GamePropertiesDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK GameOptionsProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);

static void SetStereoEnabled(HWND hWnd, int index);
static void SetYM3812Enabled(HWND hWnd, int index);
static void SetSamplesEnabled(HWND hWnd, int index);
static void InitializeOptions(HWND hDlg);
static void InitializeMisc(HWND hDlg);
static void OptOnHScroll(HWND hWnd, HWND hWndCtl, UINT code, int pos);
static void FlickerSelectionChange(HWND hWnd);
static void BeamSelectionChange(HWND hWnd);
static void GammaSelectionChange(HWND hWnd);
static void BrightnessSelectionChange(HWND hWnd);
static void DepthSelectionChange(HWND hWnd, HWND hWndCtrl);
static void ScreenDepthSelectionChange(HWND hWnd, HWND hWndCtrl);
static void DisplayChange(HWND hWnd);
static void VolumeSelectionChange(HWND hWnd);
static void SoundDelaySelectionChange(HWND hWnd);
static void RateSelectionChange(HWND hWnd);
static void UpdateDisplayModeUI(HWND hWnd, DWORD dwDepth, DWORD dwScreenDepth);
static void InitializeDisplayModeUI(HWND hWnd);
static void InitializeSoundUI(HWND hWnd);
static void InitializeDisplayTypeUI(HWND hWnd);
static void InitializeSkippingUI(HWND hWnd);
static void InitializeRotateUI(HWND hWnd);
static void InitializeDepthUI(HWND hWnd);
static void InitializeDefaultInputUI(HWND hWnd);
static void InitializeScanlineBrightnessUI(HWND hWnd);
static void InitializeStretchScaleUI(HWND hWnd);
static void InitializeJoyidUI(HWND hWnd);

#ifdef NEOGEO_BIOS_SELECT
static void InitializeBiosUI(HWND hWnd);
#endif /* NEOGEO_BIOS_SELECT */

static void PropToOptions(HWND hWnd, options_type *o);
static void OptionsToProp(HWND hWnd, options_type *o);
static void SetPropEnabledControls(HWND hWnd);

static void BuildDataMap(void);
static void ResetDataMap(void);

static void HistoryFixBuf(char *buf);

/**************************************************************
 * Local private variables
 **************************************************************/

static options_type  origGameOpts;
static options_type* lpGameOpts = NULL;

static int  iGame         = 0;
static BOOL bUseDefaults  = FALSE;
static BOOL bReset        = FALSE;
static BOOL bFullScreen   = 0;
static int  nSampleRate   = 0;
static int  nVolume       = 0;
static int  nSoundDelay   = 0;
static int  nDepth        = 0;
static int  nScreenDepth  = 0;
static int  nGamma        = 0;
static int  nBeam         = 0;
static int  nSLBrightness = 0;
static int  nScale        = 0;
static int  nRate         = 0;
#ifdef MAME_AVI
static int nRecordingSampleRate = 0;
#endif /* MAME_AVI */

/* Game history variables */
#define MAX_HISTORY_LEN     (8 * 1024)

static char   historyBuf[MAX_HISTORY_LEN];
static char   tempHistoryBuf[MAX_HISTORY_LEN];

/* Property sheets */
static DWORD dwDlgId[] = {
    IDD_PROP_GAME,
    IDD_PROP_AUDIT,
    IDD_PROP_DISPLAY,
    IDD_PROP_RENDER,
    IDD_PROP_SOUND,
    IDD_PROP_INPUT,
    IDD_PROP_MISC,
    IDD_PROP_VECTOR
};

#define NUM_PROPSHEETS (sizeof(dwDlgId) / sizeof(dwDlgId[0]))

#ifndef MAME32HELP
#define MAME32HELP "mame32jp.chm"
#endif

/* Help IDs */
static DWORD dwHelpIDs[] = {
    IDC_PROP_RESET,            IDH_PROP_RESET,
    IDC_USE_DEFAULT,           IDH_USE_DEFAULT,
    IDC_SIZES,                 IDH_SIZES,
    IDC_FULLSCREEN,            IDH_FULLSCREEN,
    IDC_DISPLAYS,              IDH_DISPLAYS,
    IDC_DEPTH,                 IDH_DEPTH,
    IDC_SCREENDEPTH,           IDH_SCREENDEPTH,
    IDC_BRIGHTNESS,            IDH_BRIGHTNESS,
    IDC_GAMMA,                 IDH_GAMMA,
    IDC_AUTOFRAMESKIP,         IDH_AUTOFRAMESKIP,
    IDC_FRAMESKIP,             IDH_FRAMESKIP,
    IDC_ROTATE,                IDH_ROTATE,
    IDC_FLIPX,                 IDH_FLIPX,
    IDC_FLIPY,                 IDH_FLIPY,
    IDC_ADJUSTASPECT,          IDH_ADJUSTASPECT,
#ifdef FSSTRETCH
    IDC_FAT_MODE,              IDH_FAT_MODE,
#endif
    IDC_DOUBLE,                IDH_DOUBLE,
#ifdef SAI
    IDC_DOUBLEF,               IDH_DOUBLEF,
#endif
    IDC_HSCANLINES,            IDH_HSCANLINES,
    IDC_VSCANLINES,            IDH_VSCANLINES,
    IDC_SLBRIGHT,              IDH_SLBRIGHT,
    IDC_HWSTRETCH,             IDH_HWSTRETCH,
    IDC_STRETCHSCALE,          IDH_STRETCHSCALE,
    IDC_TRIPLE_BUFFER,         IDH_TRIPLE_BUFFER,
    IDC_TBVSYNC,               IDH_TBVSYNC,
    IDC_WAITVSYNC,             IDH_WAITVSYNC,
    IDC_SLEEP,                 IDH_SLEEP,
    IDC_USE_HEL,               IDH_USE_HEL,
    IDC_USE_SYSMEM,            IDH_USE_SYSMEM,
    IDC_SOUNDTYPE,             IDH_SOUNDTYPE,
    IDC_SAMPLERATE,            IDH_SAMPLERATE,
    IDC_VOLUME,                IDH_VOLUME,
    IDC_SOUNDDELAY,            IDH_SOUNDDELAY,
    IDC_USE_FM_YM3812,         IDH_USE_FM_YM3812,
    IDC_STEREO,                IDH_STEREO,
    IDC_SAMPLES,               IDH_SAMPLES,
    IDC_USE_FILTER,            IDH_USE_FILTER,
    IDC_JOYSTICK,              IDH_JOYSTICK,
    IDC_DIJOYSTICK,            IDH_DIJOYSTICK,
    IDC_JOYID1,                IDH_JOYID1,
    IDC_JOYID2,                IDH_JOYID2,
    IDC_JOYID3,                IDH_JOYID3,
    IDC_JOYID4,                IDH_JOYID4,
    IDC_AI_MOUSE,              IDH_AI_MOUSE,
    IDC_DIMOUSE,               IDH_DIMOUSE,
    IDC_DIKEYBOARD,            IDH_DIKEYBOARD,
    IDC_DEFAULT_INPUT,         IDH_DEFAULT_INPUT,
    IDC_ARTWORK,               IDH_ARTWORK,
    IDC_CHEAT,                 IDH_CHEAT,
    IDC_AUTO_PAUSE,            IDH_AUTO_PAUSE,
    IDC_DISABLE_MMX,           IDH_DISABLE_MMX,
    IDC_DISABLE_MMX2,          IDH_DISABLE_MMX2,
    IDC_DISABLE_PCOUNTER,      IDH_DISABLE_PCOUNTER,
    IDC_LOG,                   IDH_LOG,
#ifdef NFILTER
    IDC_NFILTER,               IDH_NFILTER,
#endif
    IDC_ANTIALIAS,             IDH_ANTIALIAS,
    IDC_TRANSLUCENCY,          IDH_TRANSLUCENCY,
    IDC_BEAM,                  IDH_BEAM,
    IDC_FLICKER,               IDH_FLICKER,
    IDC_FILTER_VECTOR,         IDH_FILTER_VECTOR,
    IDC_FILTER_RASTER,         IDH_FILTER_RASTER,
    IDC_FILTER_CLONES,         IDH_FILTER_CLONES,
    IDC_FILTER_ORIGINALS,      IDH_FILTER_ORIGINALS,
    IDC_FILTER_WORKING,        IDH_FILTER_WORKING,
    IDC_FILTER_NONWORKING,     IDH_FILTER_NONWORKING,
    IDC_FILTER_AVAILABLE,      IDH_FILTER_AVAILABLE,
    IDC_FILTER_UNAVAILABLE,    IDH_FILTER_UNAVAILABLE,
    IDC_FILTER_NEOGEO,         IDH_FILTER_NEOGEO,
    IDC_FILTER_EDIT,           IDH_FILTER_EDIT,
    IDC_RESET_UI,              IDH_RESET_UI,
    IDC_RESET_DEFAULT,         IDH_RESET_DEFAULT,
    IDC_RESET_GAMES,           IDH_RESET_GAMES,
    IDC_RESET_FILTERS,         IDH_RESET_FILTERS,
    IDC_START_GAME_CHECK,      IDH_START_GAME_CHECK,
    IDC_START_VERSION_WARN,    IDH_START_VERSION_WARN,
    IDC_START_MMX_CHECK,       IDH_START_MMX_CHECK,
    IDC_HISTORY,               IDH_HISTORY,
    0,                         0
};

/***************************************************************
 * Public functions
 ***************************************************************/

DWORD GetHelpIDs(void)
{
    return (DWORD) (LPSTR) dwHelpIDs;
}

/* Checks of all ROMs are available for 'game' and returns result
 * Returns TRUE if all ROMs found, 0 if any ROMs are missing.
 */
BOOL FindRomSet(int game)
{
    const struct RomModule  *region, *rom;
    const struct GameDriver *gamedrv;
    const char              *name;
    int                     err;
    unsigned int            length, icrc;

    gamedrv = drivers[game];

    if (!osd_faccess(gamedrv->name, OSD_FILETYPE_ROM))
    {
        /* if the game is a clone, try loading the ROM from the main version */
        if (gamedrv->clone_of == 0
        ||  (gamedrv->clone_of->flags & NOT_A_DRIVER)
        ||  !osd_faccess(gamedrv->clone_of->name, OSD_FILETYPE_ROM))
            return FALSE;
    }

    /* loop over regions, then over files */
    for (region = rom_first_region(gamedrv); region; region = rom_next_region(region))
    {
        for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
        {
            extern struct GameDriver driver_0;
            const struct GameDriver *drv;

            name = ROM_GETNAME(rom);
            icrc = ROM_GETCRC(rom);
            length = 0;

            /* obtain CRC-32 and length of ROM file */
            drv = gamedrv;
            do
            {
                err = osd_fchecksum(drv->name, name, &length, &icrc);
                drv = drv->clone_of;
            } while (err && drv && drv != &driver_0);

            if (err)
                return FALSE;
        }
    }

    return TRUE;
}

/* Checks if the game uses external samples at all
 * Returns TRUE if this driver expects samples
 */
BOOL GameUsesSamples(int game)
{
#if (HAS_SAMPLES == 1)

    int i;
//    static const struct GameDriver *gamedrv;
	struct InternalMachineDriver drv;

//    gamedrv = drivers[game];
	expand_machine_driver(drivers[game]->drv, &drv);

    for (i = 0; drv.sound[i].sound_type && i < MAX_SOUND; i++)
    {
        const char **samplenames = NULL;

#if (HAS_SAMPLES == 1)
        if (drv.sound[i].sound_type == SOUND_SAMPLES)
            samplenames = ((struct Samplesinterface *)drv.sound[i].sound_interface)->samplenames;
#endif

        if (samplenames != 0 && samplenames[0] != 0)
            return TRUE;
    }

#endif

    return FALSE;
}

/* Checks for all samples in a sample set.
 * Returns TRUE if all samples are found, FALSE if any are missing.
 */
BOOL FindSampleSet(int game)
{
#if (HAS_SAMPLES == 1)

    static const struct GameDriver *gamedrv;
    const char* sharedname;
    BOOL bStatus;
    int  skipfirst;
    int  j, i;
	struct InternalMachineDriver drv;

    if (GameUsesSamples(game) == FALSE)
        return TRUE;

    gamedrv = drivers[game];
	expand_machine_driver(drivers[game]->drv, &drv);

    for (i = 0; drv.sound[i].sound_type && i < MAX_SOUND; i++)
    {
        const char **samplenames = NULL;

#if (HAS_SAMPLES == 1)
        if (drv.sound[i].sound_type == SOUND_SAMPLES)
            samplenames = ((struct Samplesinterface *)drv.sound[i].sound_interface)->samplenames;
#endif

        if (samplenames != 0 && samplenames[0] != 0)
        {
            BOOL have_samples = FALSE;
            BOOL have_shared  = FALSE;

            if (samplenames[0][0]=='*')
            {
                sharedname = samplenames[0]+1;
                skipfirst = 1;
            }
            else
            {
                sharedname = NULL;
                skipfirst = 0;
            }

            /* do we have samples for this game? */
            have_samples = osd_faccess(gamedrv->name, OSD_FILETYPE_SAMPLE);

            /* try shared samples */
            if (skipfirst)
                have_shared = osd_faccess(sharedname, OSD_FILETYPE_SAMPLE);

            /* if still not found, we're done */
            if (!have_samples && !have_shared)
                return FALSE;

            for (j = skipfirst; samplenames[j] != 0; j++)
            {
                bStatus = FALSE;

                /* skip empty definitions */
                if (strlen(samplenames[j]) == 0)
                    continue;

                if (have_samples)
                    bStatus = File_Status(gamedrv->name, samplenames[j], OSD_FILETYPE_SAMPLE);

                if (!bStatus && have_shared)
                {
                    bStatus = File_Status(sharedname, samplenames[j], OSD_FILETYPE_SAMPLE);
                    if (!bStatus)
                    {
                        return FALSE;
                    }
                }
            }
        }
    }

#endif

    return TRUE;
}

void InitDefaultPropertyPage(HINSTANCE hInst, HWND hWnd)
{
    PROPSHEETHEADER pshead;
    PROPSHEETPAGE   pspage[NUM_PROPSHEETS];
    int             i;
    int             maxPropSheets;

    iGame = -1;
    maxPropSheets = NUM_PROPSHEETS - 2;

    /* Get default options to populate property sheets */
    lpGameOpts = GetDefaultOptions();
    bUseDefaults = FALSE;
    /* Stash the result for comparing later */
    memcpy(&origGameOpts, lpGameOpts, sizeof(options_type));
    bReset = FALSE;
    BuildDataMap();

    ZeroMemory(&pshead, sizeof(PROPSHEETHEADER));
    ZeroMemory(pspage, sizeof(PROPSHEETPAGE) * maxPropSheets);

    /* Fill in the property sheet header */
    pshead.hwndParent     = hWnd;
    pshead.dwSize         = sizeof(PROPSHEETHEADER);
    pshead.dwFlags        = PSH_PROPSHEETPAGE | PSH_USEICONID |
                            PSH_PROPTITLE;
    pshead.hInstance      = hInst;
#ifdef JAPANESE
    pshead.pszCaption     = "標準のゲーム";
#else
    pshead.pszCaption     = "Default Game";
#endif
    pshead.nPages         = maxPropSheets;
    pshead.nStartPage     = 0;
    pshead.pszIcon        = MAKEINTRESOURCE(IDI_MAME32_ICON);
    pshead.ppsp           = pspage;

    /* Fill out the property page templates */
    for (i = 0; i < maxPropSheets; i++)
    {
        pspage[i].dwSize      = sizeof(PROPSHEETPAGE);
        pspage[i].dwFlags     = 0;
        pspage[i].hInstance   = hInst;
        pspage[i].pszTemplate = MAKEINTRESOURCE(dwDlgId[i + 2]);
        pspage[i].pfnCallback = NULL;
        pspage[i].lParam      = 0;
        pspage[i].pfnDlgProc  = GameOptionsProc;
    }
    pspage[2 - 2].pfnDlgProc = GameOptionsProc;

    /* Create the Property sheet and display it */
    if (PropertySheet(&pshead) == -1)
    {
        char temp[100];
        DWORD dwError = GetLastError();
#ifdef JAPANESE
        sprintf(temp, "プロパティシートのエラーです %ld %lX", dwError, dwError);
        MessageBox(0, temp, MAME32NAME " - プロパティシートのエラー", IDOK);
#else
        sprintf(temp, "Propery Sheet Error %ld %lX", dwError, dwError);
        MessageBox(0, temp, "Error", IDOK);
#endif
    }
}


void InitPropertyPage(HINSTANCE hInst, HWND hWnd, int game_num)
{
    InitPropertyPageToPage(hInst, hWnd, game_num, PROPERTIES_PAGE);
}

void InitPropertyPageToPage(HINSTANCE hInst, HWND hWnd, int game_num,int start_page)
{
    PROPSHEETHEADER pshead;
    PROPSHEETPAGE   pspage[NUM_PROPSHEETS];
    int             i;
    int             maxPropSheets;
	struct InternalMachineDriver drv;

    InitGameAudit(game_num);
    iGame = game_num;
	expand_machine_driver(drivers[iGame]->drv, &drv);
    maxPropSheets = (drv.video_attributes & VIDEO_TYPE_VECTOR) ? NUM_PROPSHEETS : NUM_PROPSHEETS - 1;

    /* Get Game options to populate property sheets */
    lpGameOpts = GetGameOptions(game_num);
    bUseDefaults = lpGameOpts->use_default;
    /* Stash the result for comparing later */
    memcpy(&origGameOpts, lpGameOpts, sizeof(options_type));
    bReset = FALSE;
    BuildDataMap();

    ZeroMemory(&pshead, sizeof(PROPSHEETHEADER));
    ZeroMemory(pspage, sizeof(PROPSHEETPAGE) * maxPropSheets);

    /* Fill in the property sheet header */
    pshead.hwndParent     = hWnd;
    pshead.dwSize         = sizeof(PROPSHEETHEADER);
    pshead.dwFlags        = PSH_PROPSHEETPAGE | PSH_USEICONID |
                            PSH_PROPTITLE;
    pshead.hInstance      = hInst;
    pshead.pszCaption     = GetDescriptionByIndex(iGame);
    pshead.nPages         = maxPropSheets;
    pshead.nStartPage     = start_page;
    pshead.pszIcon        = MAKEINTRESOURCE(IDI_MAME32_ICON);
    pshead.ppsp           = pspage;

    /* Fill out the property page templates */
    for (i = 0; i < maxPropSheets; i++)
    {
        pspage[i].dwSize      = sizeof(PROPSHEETPAGE);
        pspage[i].dwFlags     = 0;
        pspage[i].hInstance   = hInst;
        pspage[i].pszTemplate = MAKEINTRESOURCE(dwDlgId[i]);
        pspage[i].pfnCallback = NULL;
        pspage[i].lParam      = 0;
    }

    pspage[0].pfnDlgProc = GamePropertiesDialogProc;
    pspage[1].pfnDlgProc = GameAuditDialogProc;

    pspage[2].pfnDlgProc = GameOptionsProc;
    pspage[3].pfnDlgProc = GameOptionsProc;
    pspage[4].pfnDlgProc = GameOptionsProc;
    pspage[5].pfnDlgProc = GameOptionsProc;
    pspage[6].pfnDlgProc = GameOptionsProc;

    /* If this is a vector game, add the vector prop sheet */
    if (maxPropSheets == NUM_PROPSHEETS)
    {
        pspage[NUM_PROPSHEETS - 1].pfnDlgProc = GameOptionsProc;
    }

    /* Create the Property sheet and display it */
    if (PropertySheet(&pshead) == -1)
    {
        char temp[100];
        DWORD dwError = GetLastError();
#ifdef JAPANESE
        sprintf(temp, "プロパティシートのエラーです %ld %lX", dwError, dwError);
        MessageBox(0, temp, MAME32NAME " - プロパティシートのエラー", IDOK);
#else
        sprintf(temp, "Propery Sheet Error %ld %lX", dwError, dwError);
        MessageBox(0, temp, "Error", IDOK);
#endif
    }
}

/*********************************************************************
 * Local Functions
 *********************************************************************/

/* Build CPU info string */
char *GameInfoCPU(UINT nIndex)
{
    int i;
    static char buf[1024] = "";
	struct InternalMachineDriver drv;
	expand_machine_driver(drivers[nIndex]->drv, &drv);

    ZeroMemory(buf, sizeof(buf));
    i = 0;
    while (i < MAX_CPU && drv.cpu[i].cpu_type)
    {
        if (drv.cpu[i].cpu_clock >= 1000000)
            sprintf(&buf[strlen(buf)], "%s %d.%06d MHz",
                    cputype_name(drv.cpu[i].cpu_type),
                    drv.cpu[i].cpu_clock / 1000000,
                    drv.cpu[i].cpu_clock % 1000000);
        else
            sprintf(&buf[strlen(buf)], "%s %d.%03d kHz",
                    cputype_name(drv.cpu[i].cpu_type),
                    drv.cpu[i].cpu_clock / 1000,
                    drv.cpu[i].cpu_clock % 1000);

        if (drv.cpu[i].cpu_type & CPU_AUDIO_CPU)
            strcat(buf, " (sound)");

        strcat(buf, "\n");

        i++;
    }

    return buf;
}

/* Build Sound system info string */
char *GameInfoSound(UINT nIndex)
{
    int i;
    static char buf[1024] = "";
	struct InternalMachineDriver drv;
	expand_machine_driver(drivers[nIndex]->drv, &drv);

    ZeroMemory(buf, sizeof(buf));
    i = 0;
    while (i < MAX_SOUND && drv.sound[i].sound_type)
    {
        if (1 < sound_num(&drv.sound[i]))
            sprintf(&buf[strlen(buf)], "%d x ", sound_num(&drv.sound[i]));

        sprintf(&buf[strlen(buf)], "%s", sound_name(&drv.sound[i]));

        if (sound_clock(&drv.sound[i]))
        {
            if (sound_clock(&drv.sound[i]) >= 1000000)
                sprintf(&buf[strlen(buf)], " %d.%06d MHz",
                        sound_clock(&drv.sound[i]) / 1000000,
                        sound_clock(&drv.sound[i]) % 1000000);
            else
                sprintf(&buf[strlen(buf)], " %d.%03d kHz",
                        sound_clock(&drv.sound[i]) / 1000,
                        sound_clock(&drv.sound[i]) % 1000);
        }

        strcat(buf,"\n");

        i++;
    }
    return buf;
}

/* Build Display info string */
char *GameInfoScreen(UINT nIndex)
{
    static char buf[1024];
	struct InternalMachineDriver drv;
	expand_machine_driver(drivers[nIndex]->drv, &drv);

    if (drv.video_attributes & VIDEO_TYPE_VECTOR)
#ifdef JAPANESE
        strcpy(buf, "ベクタゲーム");
#else
        strcpy(buf, "Vector Game");
#endif
    else
    {
        if (drivers[nIndex]->flags & ORIENTATION_SWAP_XY)
            sprintf(buf, "%d x %d (vert) %5.2f Hz",
                    drv.default_visible_area.max_y - drv.default_visible_area.min_y + 1,
                    drv.default_visible_area.max_x - drv.default_visible_area.min_x + 1,
                    drv.frames_per_second);
        else
            sprintf(buf, "%d x %d (horz) %5.2f Hz",
                    drv.default_visible_area.max_x - drv.default_visible_area.min_x + 1,
                    drv.default_visible_area.max_y - drv.default_visible_area.min_y + 1,
                    drv.frames_per_second);
    }
    return buf;
}

/* Build color information string */
char *GameInfoColors(UINT nIndex)
{
    static char buf[1024];
	struct InternalMachineDriver drv;
	expand_machine_driver(drivers[nIndex]->drv, &drv);

    ZeroMemory(buf,sizeof(buf));
#ifdef JAPANESE
    if (drv.video_attributes & VIDEO_TYPE_VECTOR)
        strcpy(buf, "ベクタゲーム");
    else
        sprintf(buf, "%d 色 ", drv.total_colors);
#else
    if (drv.video_attributes & VIDEO_TYPE_VECTOR)
        strcpy(buf, "Vector Game");
    else
        sprintf(buf, "%d colors ", drv.total_colors);
#endif
    return buf;
}

/* Build game status string */
char *GameInfoStatus(UINT nIndex)
{
#ifdef JAPANESE
    switch (GetHasRoms(nIndex))
    {
    case 0:
        return "ROMが見つかりません";

    case 1:
        if (drivers[nIndex]->flags & GAME_BROKEN)
            return "動作不可";
        if (drivers[nIndex]->flags & GAME_WRONG_COLORS)
            return "色が違います";
        if (drivers[nIndex]->flags & GAME_IMPERFECT_COLORS)
            return "色の再現が不完全です";
        else
            return "動作可";

    default:
    case 2:
        return "不明";
    }
#else
    switch (GetHasRoms(nIndex))
    {
    case 0:
        return "ROMs missing";

    case 1:
        if (drivers[nIndex]->flags & GAME_BROKEN)
            return "Not working";
        if (drivers[nIndex]->flags & GAME_WRONG_COLORS)
            return "Colors are wrong";
        if (drivers[nIndex]->flags & GAME_IMPERFECT_COLORS)
            return "Imperfect Colors";
        else
            return "Working";

    default:
    case 2:
        return "Unknown";
    }
#endif
}

/* Build game manufacturer string */
char *GameInfoManufactured(UINT nIndex)
{
    static char buf[1024];

    sprintf(buf, "%s %s", drivers[nIndex]->year,drivers[nIndex]->manufacturer);
    return buf;
}

/* Build Game title string */
char *GameInfoTitle(UINT nIndex)
{
    static char buf[1024];

    if (nIndex == -1)
#ifdef JAPANESE
        strcpy(buf, "グローバルゲームオプションです。\n全ゲームのデフォルト設定として使用されます。");
#else
        strcpy(buf, "Global game options\nDefault options used by all games");
#endif
    else
        sprintf(buf, "%s\n\"%s\"", GetDescriptionByIndex(nIndex), drivers[nIndex]->name);
    return buf;
}

/* Build game clone infromation string */
char *GameInfoCloneOf(UINT nIndex)
{
    static char buf[1024];

    buf[0] = '\0';

    if (drivers[nIndex]->clone_of != 0
    &&  !(drivers[nIndex]->clone_of->flags & NOT_A_DRIVER))
    {
        sprintf(buf, "%s - \"%s\"",
                GetDescriptionByName(drivers[nIndex]->clone_of->name), drivers[nIndex]->clone_of->name);
    }

    return buf;
}

/* Handle the information property page */
static INT_PTR CALLBACK GamePropertiesDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
#ifdef MAME32JP
	extern HICON GetGameIcon(int index);
#endif

    switch (Msg)
    {
    case WM_INITDIALOG:
#if USE_SINGLELINE_TABCONTROL
        {
            HWND hWnd = PropSheet_GetTabControl(GetParent(hDlg));
            DWORD tabStyle = (GetWindowLong(hWnd,GWL_STYLE) & ~TCS_MULTILINE);
            SetWindowLong(hWnd,GWL_STYLE,tabStyle | TCS_SINGLELINE);
        }
#endif

#ifdef MAME32JP
		Static_SetIcon(GetDlgItem(hDlg, IDC_GAMEICON), GetGameIcon(iGame));
#endif

        Static_SetText(GetDlgItem(hDlg, IDC_PROP_TITLE),         GameInfoTitle(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_MANUFACTURED),  GameInfoManufactured(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_STATUS),        GameInfoStatus(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_CPU),           GameInfoCPU(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_SOUND),         GameInfoSound(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_SCREEN),        GameInfoScreen(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_COLORS),        GameInfoColors(iGame));
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_CLONEOF),       GameInfoCloneOf(iGame));
        if (drivers[iGame]->clone_of != 0
        && !(drivers[iGame]->clone_of->flags & NOT_A_DRIVER))
        {
            ShowWindow(GetDlgItem(hDlg, IDC_PROP_CLONEOF_TEXT), SW_SHOW);
        }
        else
        {
            ShowWindow(GetDlgItem(hDlg, IDC_PROP_CLONEOF_TEXT), SW_HIDE);
        }

        ShowWindow(hDlg, SW_SHOW);
        return 1;
    }
    return 0;
}

/* Handle all options property pages */
static INT_PTR CALLBACK GameOptionsProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_INITDIALOG:
        /* Fill in the Game info at the top of the sheet */
        Static_SetText(GetDlgItem(hDlg, IDC_PROP_TITLE), GameInfoTitle(iGame));
        InitializeOptions(hDlg);
        InitializeMisc(hDlg);

        PopulateControls(hDlg);
        OptionsToProp(hDlg, lpGameOpts);
        SetPropEnabledControls(hDlg);
        if (iGame == -1)
            ShowWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), SW_HIDE);
        else
            EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), (bUseDefaults) ? FALSE : TRUE);

        EnableWindow(GetDlgItem(hDlg, IDC_PROP_RESET), bReset);
        ShowWindow(hDlg, SW_SHOW);

        return 1;

    case WM_HSCROLL:
        /* slider changed */
        HANDLE_WM_HSCROLL(hDlg, wParam, lParam, OptOnHScroll);
        bUseDefaults = FALSE;
        bReset = TRUE;
        EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), TRUE);
        PropSheet_Changed(GetParent(hDlg), hDlg);
        break;

    case WM_COMMAND:
        {
            /* Below, 'changed' is used to signify the 'Apply'
             * button should be enabled.
             */
            WORD wID         = GET_WM_COMMAND_ID(wParam, lParam);
            HWND hWndCtrl    = GET_WM_COMMAND_HWND(wParam, lParam);
            WORD wNotifyCode = GET_WM_COMMAND_CMD(wParam, lParam);
            BOOL changed     = FALSE;

            switch (wID)
            {
            case IDC_FULLSCREEN:
                changed = ReadControl(hDlg, wID);
                break;

            case IDC_SOUNDTYPE:
                if (wNotifyCode == CBN_SELCHANGE)
                {
                    changed = ReadControl(hDlg, wID);
                    if (ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_SOUNDTYPE)) == 1)
                    {
                        EnableWindow(GetDlgItem(hDlg, IDC_SOUNDDELAY),     TRUE);
                        EnableWindow(GetDlgItem(hDlg, IDC_SOUNDDELAYDISP), TRUE);
                        EnableWindow(GetDlgItem(hDlg, IDC_SOUNDDELAYTEXT), TRUE);
                    }
                    else
                    {
                        EnableWindow(GetDlgItem(hDlg, IDC_SOUNDDELAY),     FALSE);
                        EnableWindow(GetDlgItem(hDlg, IDC_SOUNDDELAYDISP), FALSE);
                        EnableWindow(GetDlgItem(hDlg, IDC_SOUNDDELAYTEXT), FALSE);
                    }
                }
                break;

            case IDC_DEPTH:
                if (wNotifyCode == LBN_SELCHANGE)
                {
                    DepthSelectionChange(hDlg, hWndCtrl);
                    changed = TRUE;
                }
                break;

            case IDC_SCREENDEPTH:
                if (wNotifyCode == LBN_SELCHANGE)
                {
                    ScreenDepthSelectionChange(hDlg, hWndCtrl);
                    changed = TRUE;
                }
                break;

            case IDC_JOYSTICK:
                if (wNotifyCode == BN_CLICKED)
                {
                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_JOYSTICK)))
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_DIJOYSTICK), DIJoystick.Available());
                        Button_Enable(GetDlgItem(hDlg, IDC_DJOYSTICK), TRUE);
                    }
                    else
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_DIJOYSTICK), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_DIJOYSTICK), FALSE);
                        Button_Enable(GetDlgItem(hDlg, IDC_DJOYSTICK), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_DJOYSTICK), FALSE);
                    }
                    changed = TRUE;
                }
                break;

            case IDC_DOUBLE:
                if (wNotifyCode == BN_CLICKED)
                {
                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_DOUBLE)))
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_HSCANLINES), TRUE);
                        Button_Enable(GetDlgItem(hDlg, IDC_VSCANLINES), TRUE);
#ifdef SAI
                        Button_Enable(GetDlgItem(hDlg, IDC_DOUBLEF), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_DOUBLEF), FALSE);
#endif
                    }
                    else
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_HSCANLINES), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_HSCANLINES), FALSE);
                        Button_Enable(GetDlgItem(hDlg, IDC_VSCANLINES), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_VSCANLINES), FALSE);
#ifdef SAI
                        Button_Enable(GetDlgItem(hDlg, IDC_DOUBLEF), TRUE);
#endif
                    }
                    changed = TRUE;
                }
                break;

#ifdef SAI
            case IDC_DOUBLEF:
                if (wNotifyCode == BN_CLICKED)
                {
                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_DOUBLEF)))
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_DOUBLE), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_DOUBLE), FALSE);
                    }
                    else
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_DOUBLE), TRUE);
                    }
                    changed = TRUE;
                }
                break;
#endif

#ifdef FSSTRETCH
            case IDC_HWSTRETCH:
                if (wNotifyCode == BN_CLICKED)
                {
                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_HWSTRETCH)))
                    {
                        ComboBox_Enable(GetDlgItem(hDlg, IDC_STRETCHSCALE), TRUE);
                        Button_Enable(GetDlgItem(hDlg, IDC_FAT_MODE), TRUE);
                    }
                    else
                    {
                        ComboBox_Enable(GetDlgItem(hDlg, IDC_STRETCHSCALE), FALSE);
                        Button_Enable(GetDlgItem(hDlg, IDC_FAT_MODE), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_FAT_MODE), FALSE);
                    }
                    changed = TRUE;
                }
                break;
#else
            case IDC_HWSTRETCH:
                if (wNotifyCode == BN_CLICKED)
                {
                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_HWSTRETCH)))
                        ComboBox_Enable(GetDlgItem(hDlg, IDC_STRETCHSCALE), TRUE);
                    else
                        ComboBox_Enable(GetDlgItem(hDlg, IDC_STRETCHSCALE), FALSE);
                    changed = TRUE;
                }
                break;
#endif

            case IDC_TRIPLE_BUFFER:
                if (wNotifyCode == BN_CLICKED)
                {
                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_TRIPLE_BUFFER)))
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_TBVSYNC), TRUE);
                    }
                    else
                    {
                        Button_Enable(GetDlgItem(hDlg, IDC_TBVSYNC), FALSE);
                        Button_SetCheck(GetDlgItem(hDlg, IDC_TBVSYNC), TRUE);
                    }
                    changed = TRUE;
                }
                break;

            case IDC_SIZES:
            case IDC_FRAMESKIP:
            case IDC_DEFAULT_INPUT:
            case IDC_ROTATE:
            case IDC_SAMPLERATE:
#ifdef MAME_AVI
			case IDC_RECORDING_SAMPLERATE:
#endif /* MAME_AVI */
#ifdef NEOGEO_BIOS_SELECT
			case IDC_BIOSTYPE:
#endif /* NEOGEO_BIOS_SELECT */
            case IDC_JOYID1:
            case IDC_JOYID2:
            case IDC_JOYID3:
            case IDC_JOYID4:
                if (wNotifyCode == CBN_SELCHANGE)
                    changed = TRUE;
                break;

#ifdef ROMPATCH
            case IDC_PATCH_ROMS:
                changed = ReadControl(hDlg, wID);
                break;
#endif

            case IDC_PROP_RESET:
                if (wNotifyCode != BN_CLICKED)
                    break;

                memcpy(lpGameOpts, &origGameOpts, sizeof(options_type));
                BuildDataMap();
                PopulateControls(hDlg);
                OptionsToProp(hDlg, lpGameOpts);
                SetPropEnabledControls(hDlg);
                bReset = FALSE;
                PropSheet_UnChanged(GetParent(hDlg), hDlg);
                bUseDefaults = lpGameOpts->use_default;
                EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), (bUseDefaults) ? FALSE : TRUE);
                break;

            case IDC_USE_DEFAULT:
                if (iGame != -1)
                {
                    lpGameOpts->use_default = TRUE;
                    lpGameOpts = GetGameOptions(iGame);
                    bUseDefaults = lpGameOpts->use_default;
                    BuildDataMap();
                    PopulateControls(hDlg);
                    OptionsToProp(hDlg, lpGameOpts);
                    SetPropEnabledControls(hDlg);
                    if (origGameOpts.use_default != bUseDefaults)
                    {
                        PropSheet_Changed(GetParent(hDlg), hDlg);
                        bReset = TRUE;
                    }
                    else
                    {
                        PropSheet_UnChanged(GetParent(hDlg), hDlg);
                        bReset = FALSE;
                    }
                    EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), (bUseDefaults) ? FALSE : TRUE);
                }

                break;

            case IDC_DISPLAYS:
                if (wNotifyCode == LBN_SELCHANGE)
                {
                    DisplayChange(hDlg);
                    changed = TRUE;
                }
                break;

            default:
                if (wNotifyCode == BN_CLICKED)
                {
                    switch (wID)
                    {
                    case IDC_HSCANLINES:
                        if (Button_GetCheck(GetDlgItem(hDlg, IDC_HSCANLINES)))
                            Button_SetCheck(GetDlgItem(hDlg, IDC_VSCANLINES), FALSE);
                        break;

                    case IDC_VSCANLINES:
                        if (Button_GetCheck(GetDlgItem(hDlg, IDC_VSCANLINES)))
                            Button_SetCheck(GetDlgItem(hDlg, IDC_HSCANLINES), FALSE);
                        break;
                    }

                    if (Button_GetCheck(GetDlgItem(hDlg, IDC_HSCANLINES))
                    ||  Button_GetCheck(GetDlgItem(hDlg, IDC_VSCANLINES)))
                        ComboBox_Enable(GetDlgItem(hDlg, IDC_SLBRIGHT), TRUE);
                    else
                        ComboBox_Enable(GetDlgItem(hDlg, IDC_SLBRIGHT), FALSE);

                    changed = TRUE;
                }
            }

            /* Enable the apply button */
            if (changed == TRUE)
            {
                lpGameOpts->use_default = bUseDefaults = FALSE;
                PropSheet_Changed(GetParent(hDlg), hDlg);
                bReset = TRUE;
                EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), (bUseDefaults) ? FALSE : TRUE);
            }
            SetPropEnabledControls(hDlg);
        }
        break;

    case WM_NOTIFY:
        switch (((NMHDR *) lParam)->code)
        {
        case PSN_SETACTIVE:
            /* Initialize the controls. */
            PopulateControls(hDlg);
            OptionsToProp(hDlg, lpGameOpts);
            SetPropEnabledControls(hDlg);
            EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), (bUseDefaults) ? FALSE : TRUE);
            break;

        case PSN_APPLY:
            /* Save and apply the options here */
            PropToOptions(hDlg, lpGameOpts);
            ReadControls(hDlg);
            lpGameOpts->use_default = bUseDefaults;
            if (iGame == -1)
                lpGameOpts = GetDefaultOptions();
            else
                lpGameOpts = GetGameOptions(iGame);

            memcpy(&origGameOpts, lpGameOpts, sizeof(options_type));
            BuildDataMap();
            PopulateControls(hDlg);
            OptionsToProp(hDlg, lpGameOpts);
            SetPropEnabledControls(hDlg);
            EnableWindow(GetDlgItem(hDlg, IDC_USE_DEFAULT), (bUseDefaults) ? FALSE : TRUE);
            bReset = FALSE;
            PropSheet_UnChanged(GetParent(hDlg), hDlg);
            SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
            break;

        case PSN_KILLACTIVE:
            /* Save Changes to the options here. */
            ReadControls(hDlg);
            ResetDataMap();
            lpGameOpts->use_default = bUseDefaults;
            PropToOptions(hDlg, lpGameOpts);
            SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
            return 1;

        case PSN_RESET:
            /* Reset to the original values. Disregard changes */
            memcpy(lpGameOpts, &origGameOpts, sizeof(options_type));
            SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
            break;

        case PSN_HELP:
            /* User wants help for this property page */
            break;
        }
        break;

    case WM_HELP:
        HtmlHelp(((LPHELPINFO)lParam)->hItemHandle, MAME32HELP, HH_TP_HELP_WM_HELP, GetHelpIDs());
        break;

    case WM_CONTEXTMENU:
        HtmlHelp((HWND)wParam, MAME32HELP, HH_TP_HELP_CONTEXTMENU, GetHelpIDs());
        break;
    }
    EnableWindow(GetDlgItem(hDlg, IDC_PROP_RESET), bReset);

    return 0;
}

/* Read controls that are not handled in the DataMap */
void PropToOptions(HWND hWnd, options_type *o)
{
    char buf[100];
    HWND hCtrl;

    o->use_default = bUseDefaults;

    /* Game Display Options box */
    hCtrl = GetDlgItem(hWnd, IDC_SIZES);
    if (hCtrl)
    {
        int index;

        /* Screen size control */
        index = ComboBox_GetCurSel(hCtrl);
        o->switchres = (index > 0) ? FALSE : TRUE;

        if (!o->switchres)
        {
            DWORD w, h, r;

            ComboBox_GetText(hCtrl, buf, 100);
            if (sscanf(buf, "%ldx%ld %ldHz", &w, &h, &r) == 3)
            {
                o->width  = w;
                o->height = h;
                o->refreshrate = r;
            }
            else
            {
                o->switchres = TRUE;
            }
        }
    }
}

/* Populate controls that are not handled in the DataMap */
void OptionsToProp(HWND hWnd, options_type *o)
{
    HWND hCtrl;
    char buf[100];

    hCtrl = GetDlgItem(hWnd, IDC_SIZES);
    if (hCtrl)
    {
        /* Screen size drop down list */
        if (o->switchres)
        {
            ComboBox_SetCurSel(hCtrl, 0);
        }
        else
        {
            /* Select the mode in the list. */
            int nSelection = 0;
            int nCount = 0;

            /* Get the number of items in the control */
            nCount = ComboBox_GetCount(hCtrl);

            while (0 < nCount--)
            {
                int nWidth, nHeight, nRefreshRate;

                /* Get the screen size */
                ComboBox_GetLBText(hCtrl, nCount, buf);

                if (sscanf(buf, "%dx%d %dHz", &nWidth, &nHeight, &nRefreshRate) == 3)
                {
                    /* If we match, set nSelection to the right value */
                    if (o->width  == nWidth
                    &&  o->height == nHeight
                    &&  o->refreshrate == nRefreshRate)
                    {
                        nSelection = nCount;
                        break;
                    }
                }
            }
            ComboBox_SetCurSel(hCtrl, nSelection);
        }
    }
    /* Gamma */
    hCtrl = GetDlgItem(hWnd, IDC_GAMMADISP);
    if (hCtrl)
    {
        /* Set the static display to the new value */
        sprintf(buf, "%03.02f", o->gamma_correct);
        Static_SetText(hCtrl, buf);
    }

    hCtrl = GetDlgItem(hWnd, IDC_BRIGHTNESSDISP);
    if (hCtrl)
    {
        /* Set the static display to the new value */
        sprintf(buf, "%3d%%", o->brightness);
        Static_SetText(hCtrl, buf);
    }

    hCtrl = GetDlgItem(hWnd, IDC_FLICKERDISP);
    if (hCtrl)
    {
        /* Now set the static flicker display the new value to match */
        sprintf(buf, "%3d", o->flicker);
        Static_SetText(hCtrl, buf);
    }

    hCtrl = GetDlgItem(hWnd, IDC_BEAMDISP);
    if (hCtrl)
    {
        /* Set the static display to the new value */
        sprintf(buf, "%03.02f", o->beam);
        Static_SetText(hCtrl, buf);
    }

    hCtrl = GetDlgItem(hWnd, IDC_VOLUMEDISP);
    if (hCtrl)
    {
        /* Set the static display to the new value */
        sprintf(buf, "%ddB", - o->attenuation);
        Static_SetText(hCtrl, buf);
    }

    hCtrl = GetDlgItem(hWnd, IDC_SOUNDDELAYDISP);
    if (hCtrl)
    {
        /* Set the static display to the new value */
        sprintf(buf, "%dframes", o->sound_delay);
        Static_SetText(hCtrl, buf);
    }

    hCtrl = GetDlgItem(hWnd, IDC_TRANSDISP);
    if (hCtrl)
    {
        /* Set the static display to the new value */
        sprintf(buf, "%3d%%", o->transparency_rate);
        Static_SetText(hCtrl, buf);
    }

    /* update list of modes for this display by simulating a display change */
    DisplayChange(hWnd);

}

/* Adjust controls - tune them to the currently selected game */
void SetPropEnabledControls(HWND hWnd)
{
    HWND hCtrl;
    int  nIndex;
    int  window_mode, sound;

    nIndex = iGame;

    window_mode = !bFullScreen;

    /* Display options */
    ComboBox_Enable(GetDlgItem(hWnd, IDC_DISPLAYS), (window_mode == FALSE) && (DirectDraw_GetNumDisplays() > 1));

    if (Button_GetCheck(GetDlgItem(hWnd, IDC_AUTOFRAMESKIP)))
        EnableWindow(GetDlgItem(hWnd, IDC_FRAMESKIP), FALSE);
    else
        EnableWindow(GetDlgItem(hWnd, IDC_FRAMESKIP), TRUE);

    /* Common render options */
    if (Button_GetCheck(GetDlgItem(hWnd, IDC_DOUBLE)))
    {
        Button_Enable(GetDlgItem(hWnd, IDC_HSCANLINES), TRUE);
        Button_Enable(GetDlgItem(hWnd, IDC_VSCANLINES), TRUE);
#ifdef SAI
        Button_Enable(GetDlgItem(hWnd, IDC_DOUBLEF), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_DOUBLEF), FALSE);
#endif
    }
    else
    {
        Button_Enable(GetDlgItem(hWnd, IDC_HSCANLINES), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_HSCANLINES), FALSE);
        Button_Enable(GetDlgItem(hWnd, IDC_VSCANLINES),  FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_VSCANLINES), FALSE);
#ifdef SAI
        Button_Enable(GetDlgItem(hWnd, IDC_DOUBLEF), TRUE);
#endif
    }
#ifdef SAI
    if (Button_GetCheck(GetDlgItem(hWnd, IDC_DOUBLEF)))
    {
        Button_Enable(GetDlgItem(hWnd, IDC_DOUBLE), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_DOUBLE), FALSE);
    }
    else
    {
        Button_Enable(GetDlgItem(hWnd, IDC_DOUBLE), TRUE);
    }
#endif
    if (Button_GetCheck(GetDlgItem(hWnd, IDC_HSCANLINES))
    ||  Button_GetCheck(GetDlgItem(hWnd, IDC_VSCANLINES)))
    {
        ComboBox_Enable(GetDlgItem(hWnd, IDC_SLBRIGHT), TRUE);
    }
    else
    {
        ComboBox_Enable(GetDlgItem(hWnd, IDC_SLBRIGHT), FALSE);
    }
#ifdef FSSTRETCH
    if (Button_GetCheck(GetDlgItem(hWnd, IDC_HWSTRETCH)))
    {
        ComboBox_Enable(GetDlgItem(hWnd, IDC_STRETCHSCALE), TRUE);
        Button_Enable(GetDlgItem(hWnd, IDC_FAT_MODE), TRUE);
    }
    else
    {
        ComboBox_Enable(GetDlgItem(hWnd, IDC_STRETCHSCALE), FALSE);
        Button_Enable(GetDlgItem(hWnd, IDC_FAT_MODE), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_FAT_MODE), FALSE);
    }
#else
    if (Button_GetCheck(GetDlgItem(hWnd, IDC_HWSTRETCH)))
        ComboBox_Enable(GetDlgItem(hWnd, IDC_STRETCHSCALE), TRUE);
    else
        ComboBox_Enable(GetDlgItem(hWnd, IDC_STRETCHSCALE), FALSE);
#endif

    /* Fullscreen render options */
    Button_Enable(GetDlgItem(hWnd, IDC_TRIPLE_BUFFER), TRUE);
    if (Button_GetCheck(GetDlgItem(hWnd, IDC_TRIPLE_BUFFER)))
        Button_Enable(GetDlgItem(hWnd, IDC_TBVSYNC), TRUE);
    else
        Button_Enable(GetDlgItem(hWnd, IDC_TBVSYNC), FALSE);

    /* Window render options */
    Button_Enable(GetDlgItem(hWnd, IDC_WAITVSYNC), TRUE);

    /* Sound options */
    hCtrl = GetDlgItem(hWnd, IDC_SOUNDTYPE);
    if (hCtrl)
    {
        sound = ComboBox_GetCurSel(hCtrl);
        ComboBox_Enable(GetDlgItem(hWnd, IDC_SAMPLERATE), (sound != 0));
        EnableWindow(GetDlgItem(hWnd, IDC_VOLUME), (sound != 0));
        EnableWindow(GetDlgItem(hWnd, IDC_VOLUMEDISP), (sound != 0));
        EnableWindow(GetDlgItem(hWnd, IDC_SOUNDDELAY), (sound == 1));
        EnableWindow(GetDlgItem(hWnd, IDC_SOUNDDELAYDISP), (sound == 1));
        EnableWindow(GetDlgItem(hWnd, IDC_SOUNDDELAYTEXT), (sound == 1));
    }

#if 0
#ifdef MAME_AVI
	if (Button_GetCheck(GetDlgItem(hWnd, IDC_RECORDING_CMP)))
	{
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_CMP_F),					TRUE);
	}
	else
	{
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_CMP_F),					FALSE);
	}

    if (Button_GetCheck(GetDlgItem(hWnd, IDC_RECORDING_USESTATUS)))
    {
        Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_SAMPLERATE),				TRUE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_STEREO),					TRUE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_16BIT),					TRUE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_CMP),						TRUE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_STATIC_HZ),				TRUE);
		Button_Enable(GetDlgItem(hWnd, IDC_DSOUND_FIX),							FALSE);
		ComboBox_SetCurSel(GetDlgItem(hWnd, IDC_SOUNDTYPE),							2);
	}
	else
	{
        Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_SAMPLERATE),				FALSE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_STEREO),					FALSE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_16BIT),					FALSE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_CMP),						FALSE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_CMP_F),					FALSE);
		Button_Enable(GetDlgItem(hWnd, IDC_RECORDING_STATIC_HZ),				FALSE);
	}
#endif /* MAME_AVI */
#endif

    /* Joystick options */
    hCtrl = GetDlgItem(hWnd, IDC_JOYSTICK);
    Button_Enable(hCtrl, Joystick.Available());
    if (Button_GetCheck(hCtrl))
    {
        Button_Enable(GetDlgItem(hWnd, IDC_DIJOYSTICK), DIJoystick.Available());
        Button_Enable(GetDlgItem(hWnd, IDC_DJOYSTICK), TRUE);
    }
    else
    {
        Button_Enable(GetDlgItem(hWnd, IDC_DIJOYSTICK), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_DIJOYSTICK), FALSE);
        Button_Enable(GetDlgItem(hWnd, IDC_DJOYSTICK), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_DJOYSTICK), FALSE);
    }

    /* Trackball / Mouse options */
    if (nIndex == -1 || GameUsesTrackball(nIndex))
    {
        Button_Enable(GetDlgItem(hWnd, IDC_AI_MOUSE), TRUE);
        Button_Enable(GetDlgItem(hWnd, IDC_DIMOUSE), TRUE);
    }
    else
    {
        Button_Enable(GetDlgItem(hWnd, IDC_AI_MOUSE), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_AI_MOUSE), FALSE);
        Button_Enable(GetDlgItem(hWnd, IDC_DIMOUSE), FALSE);
        Button_SetCheck(GetDlgItem(hWnd, IDC_DIMOUSE), FALSE);
    }

    /* Keyboard options */
    Button_Enable(GetDlgItem(hWnd, IDC_DIKEYBOARD), DIKeyboard_Available());

    /* Turn off MMX if it's not detected */
    if (MAME32App.m_nMMXDetected & 1)
    {
        Button_Enable(GetDlgItem(hWnd, IDC_DISABLE_MMX), TRUE);
    }
    else
    {
        Button_SetCheck(GetDlgItem(hWnd, IDC_DISABLE_MMX), FALSE);
        Button_Enable(GetDlgItem(hWnd, IDC_DISABLE_MMX), FALSE);
    }
    if (MAME32App.m_nMMXDetected & 2)
    {
        Button_Enable(GetDlgItem(hWnd, IDC_DISABLE_MMX2), TRUE);
    }
    else
    {
        Button_SetCheck(GetDlgItem(hWnd, IDC_DISABLE_MMX2), FALSE);
        Button_Enable(GetDlgItem(hWnd, IDC_DISABLE_MMX2), FALSE);
    }

    SetStereoEnabled(hWnd, nIndex);
    SetYM3812Enabled(hWnd, nIndex);
    SetSamplesEnabled(hWnd, nIndex);

#ifdef ROMPATCH
	if (nIndex == -1 || GameUsesRomPatch(nIndex))
	{
		Button_Enable(GetDlgItem(hWnd, IDC_PATCH_ROMS), TRUE);
	}
	else
	{
		Button_SetCheck(GetDlgItem(hWnd, IDC_PATCH_ROMS), TRUE);
		Button_Enable(GetDlgItem(hWnd, IDC_PATCH_ROMS), FALSE);
	}
#endif

    hCtrl = GetDlgItem(hWnd, IDC_UI_TRANSPARENT);
    if (Button_GetCheck(hCtrl))
    {
        EnableWindow(GetDlgItem(hWnd, IDC_UI_TRANSPARENCY_RATE), TRUE);
        EnableWindow(GetDlgItem(hWnd, IDC_TRANSDISP), TRUE);
    }
    else
    {
        EnableWindow(GetDlgItem(hWnd, IDC_UI_TRANSPARENCY_RATE), FALSE);
        EnableWindow(GetDlgItem(hWnd, IDC_TRANSDISP), FALSE);
    }

    if ( nIndex == -1 || !stricmp(GetDriverFilename(nIndex), "neogeo.c"))/* dbg-bios */
#ifdef NEOGEO_BIOS_SELECT
	{
		ComboBox_Enable(GetDlgItem(hWnd, IDC_BIOSTYPE), TRUE);
		EnableWindow(GetDlgItem(hWnd, IDC_BIOSTYPETEXT), TRUE);
	}
	else
	{
		ComboBox_Enable(GetDlgItem(hWnd, IDC_BIOSTYPE), FALSE);
		EnableWindow(GetDlgItem(hWnd, IDC_BIOSTYPETEXT), FALSE);
	}
#endif /* NEOGEO_BIOS_SELECT */

//ks hcmame s switch m68k core
#if (HAS_M68000 || HAS_M68010 || HAS_M68EC020 || HAS_M68020)
	if (nIndex != -1)
	{
		int n;
		int has_m68k = 0;

		struct InternalMachineDriver drv;
		expand_machine_driver(drivers[nIndex]->drv,&drv);

		for (n = 0; n < MAX_CPU; n++)
			switch (drv.cpu[n].cpu_type)
			{
#if (HAS_M68000)
			case CPU_M68000:
#endif
#if (HAS_M68010)
			case CPU_M68010:
#endif
#if (HAS_M68EC020)
			case CPU_M68EC020:
#endif
#if (HAS_M68020)
			case CPU_M68020:
#endif
				has_m68k = 1;
			}

		ShowWindow(GetDlgItem(hWnd, IDC_M68K_C_CORE), has_m68k ? SW_SHOW : SW_HIDE);
	}
#else
	ShowWindow(GetDlgItem(hWnd, IDC_M68K_C_CORE), SW_HIDE);
#endif /* (HAS_M68000 || HAS_M68010 || HAS_M68EC020 || HAS_M68020) */
}

/**************************************************************
 * Control Helper functions for data exchange
 **************************************************************/
void AssignSampleRate(HWND hWnd)
{
    switch (nSampleRate)
    {
        case 0:  lpGameOpts->samplerate = 11025; break;
        case 1:  lpGameOpts->samplerate = 22050; break;
        case 2:  lpGameOpts->samplerate = 44100; break;
        case 3:  lpGameOpts->samplerate = 48000; break;
        default: lpGameOpts->samplerate = 44100; break;
    }
}

#ifdef MAME_AVI
void AssignRecordingSampleRate(HWND hWnd)
{
    switch (nRecordingSampleRate)
    {
		case 0:  lpGameOpts->recording_sample_rate = 4000;  break;
		case 1:  lpGameOpts->recording_sample_rate = 8000;  break;
		case 2:  lpGameOpts->recording_sample_rate = 11025; break;
		case 3:  lpGameOpts->recording_sample_rate = 16000; break;
		case 4:  lpGameOpts->recording_sample_rate = 18900; break;
		case 5:  lpGameOpts->recording_sample_rate = 22050; break;
		case 6:  lpGameOpts->recording_sample_rate = 24000; break;
		case 7:  lpGameOpts->recording_sample_rate = 32000; break;
		case 8:  lpGameOpts->recording_sample_rate = 37800; break;
		case 9:  lpGameOpts->recording_sample_rate = 44100; break;
		case 10: lpGameOpts->recording_sample_rate = 48000; break;
		case 11: lpGameOpts->recording_sample_rate = 64000; break;
		case 12: lpGameOpts->recording_sample_rate = 96000; break;

        default: lpGameOpts->recording_sample_rate = 22050; break;
    }
}
#endif /* MAME_AVI */

void AssignVolume(HWND hWnd)
{
    lpGameOpts->attenuation = 32 - nVolume;
}

void AssignSoundDelay(HWND hWnd)
{
    lpGameOpts->sound_delay = nSoundDelay + 1;
}

void AssignFullScreen(HWND hWnd)
{
    lpGameOpts->window_mode = !bFullScreen;
}

void AssignDepth(HWND hWnd)
{
    switch (nDepth)
    {
    case 1:  lpGameOpts->color_depth = 16; break;
    case 2:  lpGameOpts->color_depth = 32; break;
    default: lpGameOpts->color_depth =  0; break;
    }
    UpdateDisplayModeUI(hWnd, lpGameOpts->color_depth, lpGameOpts->screen_depth);
}

void AssignScreenDepth(HWND hWnd)
{
    switch (nScreenDepth)
    {
    case 1:  lpGameOpts->screen_depth = 16; break;
    case 2:  lpGameOpts->screen_depth = 24; break;
    case 3:  lpGameOpts->screen_depth = 32; break;
    default: lpGameOpts->screen_depth =  0; break;
    }
    UpdateDisplayModeUI(hWnd, lpGameOpts->color_depth, lpGameOpts->screen_depth);
}

void AssignScanlineBrightness(HWND hWnd)
{
    switch (nSLBrightness)
    {
    case 0:  lpGameOpts->sl_brightness =  0; break;
    case 1:  lpGameOpts->sl_brightness = 25; break;
    case 2:  lpGameOpts->sl_brightness = 50; break;
    case 3:  lpGameOpts->sl_brightness = 75; break;
    default: lpGameOpts->sl_brightness =  0; break;
    }
}

void AssignStretchScale(HWND hWnd)
{
    switch (nScale)
    {
    case 0:  lpGameOpts->scale =  2; break;
    case 1:  lpGameOpts->scale =  3; break;
    case 2:  lpGameOpts->scale =  4; break;
    default: lpGameOpts->scale =  1; break;
    }
}

void AssignGamma(HWND hWnd)
{
    /* Gamma control */
    lpGameOpts->gamma_correct = nGamma / 20.0 + 0.5;
}

void AssignBeam(HWND hWnd)
{
    lpGameOpts->beam = nBeam / 20.0 + 1.0;
}

void AssignRate(HWND hWnd)
{
    lpGameOpts->transparency_rate = nRate;
}
/************************************************************
 * DataMap initializers
 ************************************************************/

/* Initialize local helper variables */
void ResetDataMap(void)
{
    switch (lpGameOpts->samplerate)
    {
    case 11025: nSampleRate = 0; break;
    case 22050: nSampleRate = 1; break;
    case 44100: nSampleRate = 2; break;
    case 48000: nSampleRate = 3; break;
    default:    nSampleRate = 1; break;
    }

#ifdef MAME_AVI
	switch (lpGameOpts->recording_sample_rate)
	{
		case 4000:  nRecordingSampleRate = 0; break;
		case 8000:  nRecordingSampleRate = 1; break;
		case 11025: nRecordingSampleRate = 2; break;
		case 16000: nRecordingSampleRate = 3; break;
		case 18900: nRecordingSampleRate = 4; break;
		case 22050: nRecordingSampleRate = 5; break;
		case 24000: nRecordingSampleRate = 6; break;
		case 32000: nRecordingSampleRate = 7; break;
		case 37800: nRecordingSampleRate = 8; break;
		case 44100: nRecordingSampleRate = 9; break;
		case 48000: nRecordingSampleRate = 10; break;
		case 64000: nRecordingSampleRate = 11; break;
		case 96000: nRecordingSampleRate = 12; break;
		default: nRecordingSampleRate = 1; break;
	}
#endif /* MAME_AVI */

    switch (lpGameOpts->color_depth)
    {
    case 16: nDepth = 1; break;
    case 32: nDepth = 2; break;
    default: nDepth = 0; break;
    }

    switch (lpGameOpts->screen_depth)
    {
    case 16: nScreenDepth = 1; break;
    case 24: nScreenDepth = 2; break;
    case 32: nScreenDepth = 3; break;
    default: nScreenDepth = 0; break;
    }

    switch (lpGameOpts->sl_brightness)
    {
    case  0: nSLBrightness = 0; break;
    case 25: nSLBrightness = 1; break;
    case 50: nSLBrightness = 2; break;
    case 75: nSLBrightness = 3; break;
    default: nSLBrightness = 0; break;
    }

    switch (lpGameOpts->scale)
    {
    case  2: nScale = 0; break;
    case  3: nScale = 1; break;
    case  4: nScale = 2; break;
    default: nScale = 0; break;
    }

    nVolume     = 32 - lpGameOpts->attenuation;
    nSoundDelay = lpGameOpts->sound_delay - 1;
    bFullScreen = !lpGameOpts->window_mode;
    nGamma      = (int)((lpGameOpts->gamma_correct - 0.5) * 20.0);
    nBeam       = (int)((lpGameOpts->beam  - 1.0) * 20.0);
    nRate       = lpGameOpts->transparency_rate;
}

/* Build the control mapping by adding all needed information to the DataMap */
void BuildDataMap(void)
{
    InitDataMap();

    ResetDataMap();

    DataMapAdd(IDC_FULLSCREEN,       DM_BOOL, CT_BUTTON,   &bFullScreen,   0, 0, AssignFullScreen);
    DataMapAdd(IDC_DEPTH,            DM_INT,  CT_COMBOBOX, &nDepth,        0, 0, AssignDepth);
    DataMapAdd(IDC_SCREENDEPTH,      DM_INT,  CT_COMBOBOX, &nScreenDepth,  0, 0, AssignScreenDepth);
    DataMapAdd(IDC_SLBRIGHT,         DM_INT,  CT_COMBOBOX, &nSLBrightness, 0, 0, AssignScanlineBrightness);
    DataMapAdd(IDC_STRETCHSCALE,     DM_INT,  CT_COMBOBOX, &nScale,        0, 0, AssignStretchScale);
    DataMapAdd(IDC_SAMPLERATE,       DM_INT,  CT_COMBOBOX, &nSampleRate,   0, 0, AssignSampleRate);
    DataMapAdd(IDC_VOLUME,           DM_INT,  CT_SLIDER,   &nVolume,       0, 0, AssignVolume);
    DataMapAdd(IDC_SOUNDDELAY,       DM_INT,  CT_SLIDER,   &nSoundDelay,   0, 0, AssignSoundDelay);
    DataMapAdd(IDC_GAMMA,            DM_INT,  CT_SLIDER,   &nGamma,        0, 0, AssignGamma);
    DataMapAdd(IDC_BEAM,             DM_INT,  CT_SLIDER,   &nBeam,         0, 0, AssignBeam);
    DataMapAdd(IDC_UI_TRANSPARENCY_RATE,DM_INT,CT_SLIDER,  &nRate,         0, 0, AssignRate);

    DataMapAdd(IDC_DISPLAYS,         DM_INT,  CT_COMBOBOX, &lpGameOpts->monitor,           0, 0, 0);
    DataMapAdd(IDC_BRIGHTNESS,       DM_INT,  CT_SLIDER,   &lpGameOpts->brightness,        0, 0, 0);
    DataMapAdd(IDC_AUTOFRAMESKIP,    DM_BOOL, CT_BUTTON,   &lpGameOpts->autoframeskip,     0, 0, 0);
    DataMapAdd(IDC_FRAMESKIP,        DM_INT,  CT_COMBOBOX, &lpGameOpts->frameskip,         0, 0, 0);
    DataMapAdd(IDC_ROTATE,           DM_INT,  CT_COMBOBOX, &lpGameOpts->rotate,            0, 0, 0);
    DataMapAdd(IDC_FLIPX,            DM_BOOL, CT_BUTTON,   &lpGameOpts->flipx,             0, 0, 0);
    DataMapAdd(IDC_FLIPY,            DM_BOOL, CT_BUTTON,   &lpGameOpts->flipy,             0, 0, 0);

    DataMapAdd(IDC_ADJUSTASPECT,     DM_BOOL, CT_BUTTON,   &lpGameOpts->adjust_aspect,     0, 0, 0);
#ifdef FSSTRETCH
    DataMapAdd(IDC_FAT_MODE,         DM_BOOL, CT_BUTTON,   &lpGameOpts->fat_mode,          0, 0, 0);
#endif
    DataMapAdd(IDC_DOUBLE,           DM_BOOL, CT_BUTTON,   &lpGameOpts->double_size,       0, 0, 0);
#ifdef SAI
    DataMapAdd(IDC_DOUBLEF,          DM_BOOL, CT_BUTTON,   &lpGameOpts->double_filter,     0, 0, 0);
#endif
    DataMapAdd(IDC_HSCANLINES,       DM_BOOL, CT_BUTTON,   &lpGameOpts->hscanlines,        0, 0, 0);
    DataMapAdd(IDC_VSCANLINES,       DM_BOOL, CT_BUTTON,   &lpGameOpts->vscanlines,        0, 0, 0);
    DataMapAdd(IDC_HWSTRETCH,        DM_BOOL, CT_BUTTON,   &lpGameOpts->hw_stretch,        0, 0, 0);
    DataMapAdd(IDC_TRIPLE_BUFFER,    DM_BOOL, CT_BUTTON,   &lpGameOpts->use_triplebuf,     0, 0, 0);
    DataMapAdd(IDC_TBVSYNC,          DM_BOOL, CT_BUTTON,   &lpGameOpts->tbvsync,           0, 0, 0);
    DataMapAdd(IDC_WAITVSYNC,        DM_BOOL, CT_BUTTON,   &lpGameOpts->wait_vsync,        0, 0, 0);
    DataMapAdd(IDC_SLEEP,            DM_BOOL, CT_BUTTON,   &lpGameOpts->use_sleep,         0, 0, 0);
    DataMapAdd(IDC_USE_HEL,          DM_BOOL, CT_BUTTON,   &lpGameOpts->use_hel,           0, 0, 0);
    DataMapAdd(IDC_USE_SYSMEM,       DM_BOOL, CT_BUTTON,   &lpGameOpts->use_sysmem,        0, 0, 0);

    DataMapAdd(IDC_SOUNDTYPE,        DM_INT,  CT_COMBOBOX, &lpGameOpts->sound_type,        0, 0, 0);
    DataMapAdd(IDC_STEREO,           DM_BOOL, CT_BUTTON,   &lpGameOpts->stereo,            0, 0, 0);
    DataMapAdd(IDC_SAMPLES,          DM_BOOL, CT_BUTTON,   &lpGameOpts->use_samples,       0, 0, 0);
    DataMapAdd(IDC_USE_FILTER,       DM_BOOL, CT_BUTTON,   &lpGameOpts->use_filter,        0, 0, 0);
    DataMapAdd(IDC_FORCE_PANPOT,     DM_BOOL, CT_BUTTON,   &lpGameOpts->force_panpot,      0, 0, 0);
    DataMapAdd(IDC_LIMIT_ADJUST,     DM_BOOL, CT_BUTTON,   &lpGameOpts->limit_adjust,      0, 0, 0);
    DataMapAdd(IDC_FORMAT_VOLUME,    DM_BOOL, CT_BUTTON,   &lpGameOpts->format_volume,     0, 0, 0);
    DataMapAdd(IDC_AUTO_ADJUST,      DM_BOOL, CT_BUTTON,   &lpGameOpts->auto_adjust,       0, 0, 0);
    DataMapAdd(IDC_PRESOUNDFIX,      DM_BOOL, CT_BUTTON,   &lpGameOpts->presoundfix,       0, 0, 0);

    DataMapAdd(IDC_JOYSTICK,         DM_BOOL, CT_BUTTON,   &lpGameOpts->use_joystick,      0, 0, 0);
    DataMapAdd(IDC_DIJOYSTICK,       DM_BOOL, CT_BUTTON,   &lpGameOpts->di_joystick,       0, 0, 0);
    DataMapAdd(IDC_DJOYSTICK,        DM_BOOL, CT_BUTTON,   &lpGameOpts->use_djoystick,     0, 0, 0);
    DataMapAdd(IDC_JOYID1,           DM_INT,  CT_COMBOBOX, &lpGameOpts->joyid[0],          0, 0, 0);
    DataMapAdd(IDC_JOYID2,           DM_INT,  CT_COMBOBOX, &lpGameOpts->joyid[1],          0, 0, 0);
    DataMapAdd(IDC_JOYID3,           DM_INT,  CT_COMBOBOX, &lpGameOpts->joyid[2],          0, 0, 0);
    DataMapAdd(IDC_JOYID4,           DM_INT,  CT_COMBOBOX, &lpGameOpts->joyid[3],          0, 0, 0);
    DataMapAdd(IDC_AI_MOUSE,         DM_BOOL, CT_BUTTON,   &lpGameOpts->use_mouse,         0, 0, 0);
    DataMapAdd(IDC_DIMOUSE,          DM_BOOL, CT_BUTTON,   &lpGameOpts->di_mouse,          0, 0, 0);
    DataMapAdd(IDC_DIKEYBOARD,       DM_BOOL, CT_BUTTON,   &lpGameOpts->di_keyboard,       0, 0, 0);
    DataMapAdd(IDC_DEFAULT_INPUT,    DM_INT,  CT_COMBOBOX, &lpGameOpts->default_input,     0, 0, 0);

    DataMapAdd(IDC_ARTWORK,          DM_BOOL, CT_BUTTON,   &lpGameOpts->use_artwork,       0, 0, 0);
    DataMapAdd(IDC_CHEAT,            DM_BOOL, CT_BUTTON,   &lpGameOpts->cheat,             0, 0, 0);
    DataMapAdd(IDC_AUTO_PAUSE,       DM_BOOL, CT_BUTTON,   &lpGameOpts->auto_pause,        0, 0, 0);
    DataMapAdd(IDC_DISABLE_MMX,      DM_BOOL, CT_BUTTON,   &lpGameOpts->disable_mmx,       0, 0, 0);
    DataMapAdd(IDC_DISABLE_MMX2,     DM_BOOL, CT_BUTTON,   &lpGameOpts->disable_mmx2,      0, 0, 0);
    DataMapAdd(IDC_DISABLE_PCOUNTER, DM_BOOL, CT_BUTTON,   &lpGameOpts->disable_pcounter,  0, 0, 0);
    DataMapAdd(IDC_LOG,              DM_BOOL, CT_BUTTON,   &lpGameOpts->errorlog,          0, 0, 0);
#ifdef NFILTER
    DataMapAdd(IDC_NFILTER,          DM_BOOL, CT_BUTTON,   &lpGameOpts->nfilter,           0, 0, 0);
#endif
    DataMapAdd(IDC_UI_TRANSPARENT,   DM_BOOL, CT_BUTTON,   &lpGameOpts->transparency,      0, 0, 0);
#ifdef ROMPATCH
    DataMapAdd(IDC_PATCH_ROMS,       DM_BOOL, CT_BUTTON,   &lpGameOpts->patch_roms,        0, 0, 0);
#endif
#ifdef MAME32JP
    DataMapAdd(IDC_HISCORE_FORCE,    DM_BOOL, CT_BUTTON,   &lpGameOpts->hiscore_force,     0, 0, 0);
    DataMapAdd(IDC_HISCORE_DISABLE,  DM_BOOL, CT_BUTTON,   &lpGameOpts->hiscore_disable,   0, 0, 0);
    DataMapAdd(IDC_BLACKOUT,	     DM_BOOL, CT_BUTTON,   &lpGameOpts->blackout,	       0, 0, 0);
    DataMapAdd(IDC_AUTOFIRE_MESSAGE, DM_BOOL, CT_BUTTON,   &lpGameOpts->autofire_message,  0, 0, 0);
#endif /* MAME32JP */
#ifdef NEOGEO_BIOS_SELECT
	DataMapAdd(IDC_BIOSTYPE,         DM_INT,  CT_COMBOBOX, &lpGameOpts->bios_type,         0, 0, 0);
#endif /* NEOGEO_BIOS_SELECT */
//ks hcmame s switch m68k core
#if (HAS_M68000 || HAS_M68010 || HAS_M68EC020 || HAS_M68020)
	DataMapAdd(IDC_M68K_C_CORE,      DM_BOOL,  CT_BUTTON,  &lpGameOpts->m68k_c_core,       0, 0, 0);
#endif /* (HAS_M68000 || HAS_M68010 || HAS_M68EC020 || HAS_M68020) */
//ks hcmame e switch m68k core
    DataMapAdd(IDC_ANTIALIAS,        DM_BOOL, CT_BUTTON,   &lpGameOpts->antialias,         0, 0, 0);
    DataMapAdd(IDC_TRANSLUCENCY,     DM_BOOL, CT_BUTTON,   &lpGameOpts->translucency,      0, 0, 0);
    DataMapAdd(IDC_FLICKER,          DM_INT,  CT_SLIDER,   &lpGameOpts->flicker,           0, 0, 0);
#ifdef MAME_AVI
	DataMapAdd(IDC_RECORDING_USESTATUS,	 DM_BOOL, CT_BUTTON,   &lpGameOpts->recording_use_status,   0, 0, 0);
	DataMapAdd(IDC_RECORDING_SAMPLERATE, DM_INT,  CT_COMBOBOX, &nRecordingSampleRate,               0, 0, AssignRecordingSampleRate);
	DataMapAdd(IDC_RECORDING_STEREO,	 DM_BOOL, CT_BUTTON,   &lpGameOpts->recording_stereo,       0, 0, 0);
	DataMapAdd(IDC_RECORDING_16BIT,		 DM_BOOL, CT_BUTTON,   &lpGameOpts->recording_16bit,        0, 0, 0);
	DataMapAdd(IDC_RECORDING_CMP,		 DM_BOOL, CT_BUTTON,   &lpGameOpts->recording_samples_cmp,  0, 0, 0);
	DataMapAdd(IDC_RECORDING_CMP_F,		 DM_BOOL, CT_BUTTON,   &lpGameOpts->recording_samples_cmp_f,0, 0, 0);
#endif /* MAME_AVI */
}

static void SetStereoEnabled(HWND hWnd, int index)
{
    BOOL enabled = FALSE;
    HWND hCtrl;
	struct InternalMachineDriver drv;
	if(index != -1)
		expand_machine_driver(drivers[index]->drv, &drv);

    hCtrl = GetDlgItem(hWnd, IDC_STEREO);
    if (hCtrl)
    {
        if (index == -1 || drv.sound_attributes & SOUND_SUPPORTS_STEREO)
            enabled = TRUE;

        EnableWindow(hCtrl, enabled);
        if (!enabled)
            Button_SetCheck(hCtrl, FALSE);
    }
}

static void SetYM3812Enabled(HWND hWnd, int index)
{
    int i;
    BOOL enabled;
    HWND hCtrl;
	struct InternalMachineDriver drv;
	if(index != -1)
		expand_machine_driver(drivers[index]->drv, &drv);

    hCtrl = GetDlgItem(hWnd, IDC_USE_FM_YM3812);
    if (hCtrl)
    {
        enabled = FALSE;
        for (i = 0; i < MAX_SOUND; i++)
        {
            if (index == -1
#if HAS_YM3812
            ||  drv.sound[i].sound_type == SOUND_YM3812
#endif
#if HAS_YM3526
            ||  drv.sound[i].sound_type == SOUND_YM3526
#endif
#if HAS_YM2413
            ||  drv.sound[i].sound_type == SOUND_YM2413
#endif
            )
                enabled = TRUE;
        }

        EnableWindow(hCtrl, enabled);
        if (!enabled)
            Button_SetCheck(hCtrl, FALSE);
    }
}

static void SetSamplesEnabled(HWND hWnd, int index)
{
#if (HAS_SAMPLES == 1)
    int i;
    BOOL enabled = FALSE;
    HWND hCtrl;
	struct InternalMachineDriver drv;
	if(index != -1)
		expand_machine_driver(drivers[index]->drv, &drv);

    hCtrl = GetDlgItem(hWnd, IDC_SAMPLES);
    if (hCtrl)
    {
        for (i = 0; i < MAX_SOUND; i++)
        {
            if (index == -1
            ||  drv.sound[i].sound_type == SOUND_SAMPLES
            ||  drv.sound[i].sound_type == SOUND_VLM5030)
                enabled = TRUE;
        }

        EnableWindow(hCtrl, enabled);
        if (!enabled)
            Button_SetCheck(hCtrl, FALSE);
    }
#endif
}

/* Moved here cause it's called in a few places */
static void InitializeOptions(HWND hDlg)
{
    InitializeDepthUI(hDlg);
    InitializeDisplayTypeUI(hDlg);
    InitializeDisplayModeUI(hDlg);
    InitializeSoundUI(hDlg);
    InitializeSkippingUI(hDlg);
    InitializeRotateUI(hDlg);
    InitializeDefaultInputUI(hDlg);
    InitializeStretchScaleUI(hDlg);
    InitializeScanlineBrightnessUI(hDlg);
    InitializeJoyidUI(hDlg);
#ifdef NEOGEO_BIOS_SELECT
	InitializeBiosUI(hDlg);
#endif /* NEOGEO_BIOS_SELECT */
}

/* Moved here because it is called in several places */
static void InitializeMisc(HWND hDlg)
{
    Button_Enable(GetDlgItem(hDlg, IDC_JOYSTICK),   Joystick.Available());
    Button_Enable(GetDlgItem(hDlg, IDC_DIJOYSTICK), DIJoystick.Available());
    Button_Enable(GetDlgItem(hDlg, IDC_DJOYSTICK),  DIJoystick.Available());
    Button_Enable(GetDlgItem(hDlg, IDC_DIKEYBOARD), DIKeyboard_Available());

    SendMessage(GetDlgItem(hDlg, IDC_GAMMA), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 30)); /* 0.50 - 2.00 in .05 increments */

    SendMessage(GetDlgItem(hDlg, IDC_BRIGHTNESS), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 100));

    SendMessage(GetDlgItem(hDlg, IDC_FLICKER), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 100));

    SendMessage(GetDlgItem(hDlg, IDC_BEAM), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 300)); /* 1.00 - 16.00 in .05 increments */

    SendMessage(GetDlgItem(hDlg, IDC_VOLUME), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 32)); /* -32 - 0 */

    SendMessage(GetDlgItem(hDlg, IDC_SOUNDDELAY), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 9)); /* 1 - 10 */

    SendMessage(GetDlgItem(hDlg, IDC_UI_TRANSPARENCY_RATE), TBM_SETRANGE,
                (WPARAM)FALSE,
                (LPARAM)MAKELONG(0, 100)); /* 0 - 100 */
}

static void OptOnHScroll(HWND hWnd, HWND hWndCtl, UINT code, int pos)
{
    if (hWndCtl == GetDlgItem(hWnd, IDC_FLICKER))
    {
        FlickerSelectionChange(hWnd);
    }
    else
    if (hWndCtl == GetDlgItem(hWnd, IDC_GAMMA))
    {
        GammaSelectionChange(hWnd);
    }
    else
    if (hWndCtl == GetDlgItem(hWnd, IDC_BRIGHTNESS))
    {
        BrightnessSelectionChange(hWnd);
    }
    else
    if (hWndCtl == GetDlgItem(hWnd, IDC_BEAM))
    {
        BeamSelectionChange(hWnd);
    }
    else
    if (hWndCtl == GetDlgItem(hWnd, IDC_VOLUME))
    {
        VolumeSelectionChange(hWnd);
    }
    else
    if (hWndCtl == GetDlgItem(hWnd, IDC_SOUNDDELAY))
    {
        SoundDelaySelectionChange(hWnd);
    }
    if (hWndCtl == GetDlgItem(hWnd, IDC_UI_TRANSPARENCY_RATE))
    {
        RateSelectionChange(hWnd);
    }
}

/* Handle changes to the Flicker slider */
static void FlickerSelectionChange(HWND hWnd)
{
    char buf[100];
    int  nValue;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_FLICKER), TBM_GETPOS, 0, 0);

    /* Now set the static flicker display the new value to match */
    sprintf(buf, "%3d", nValue);
    Static_SetText(GetDlgItem(hWnd, IDC_FLICKERDISP), buf);
}

/* Handle changes to the Beam slider */
static void BeamSelectionChange(HWND hWnd)
{
    char buf[100];
    UINT nValue;
    double dBeam;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_BEAM), TBM_GETPOS, 0, 0);

    dBeam = nValue / 20.0 + 1.0;

    /* Set the static display to the new value */
    sprintf(buf, "%03.02f", dBeam);
    Static_SetText(GetDlgItem(hWnd, IDC_BEAMDISP), buf);
}


/* Handle changes to the Gamma slider */
static void GammaSelectionChange(HWND hWnd)
{
    char buf[100];
    UINT nValue;
    double dGamma;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_GAMMA), TBM_GETPOS, 0, 0);

    dGamma = nValue / 20.0 + 0.5;

    /* Set the static display to the new value */
    sprintf(buf, "%03.02f", dGamma);
    Static_SetText(GetDlgItem(hWnd, IDC_GAMMADISP), buf);
}

/* Handle changes to the Brightness slider */
static void BrightnessSelectionChange(HWND hWnd)
{
    char buf[100];
    int  nValue;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_BRIGHTNESS), TBM_GETPOS, 0, 0);

    /* Set the static display to the new value */
    sprintf(buf, "%3d%%", nValue);
    Static_SetText(GetDlgItem(hWnd, IDC_BRIGHTNESSDISP), buf);
}

/* Handle changes to the Color Depth drop down */
static void DepthSelectionChange(HWND hWnd, HWND hWndCtrl)
{
    int nCurSelection;

    nCurSelection = ComboBox_GetCurSel(hWndCtrl);
    if (nCurSelection != CB_ERR)
    {
        int nValue;

        nValue = ComboBox_GetCurSel(hWndCtrl);
        switch (nValue)
        {
        case 1:  nValue = 16; break;
        case 2:  nValue = 32; break;
        default: nValue =  0; break;
        }
        UpdateDisplayModeUI(hWnd, nValue, lpGameOpts->screen_depth);
    }
}

/* Handle changes to the Screen Color Depth drop down */
static void ScreenDepthSelectionChange(HWND hWnd, HWND hWndCtrl)
{
    int nCurSelection;

    nCurSelection = ComboBox_GetCurSel(hWndCtrl);
    if (nCurSelection != CB_ERR)
    {
        int nValue;

        nValue = ComboBox_GetCurSel(hWndCtrl);
        switch (nValue)
        {
        case 1:  nValue = 16; break;
        case 2:  nValue = 24; break;
        case 3:  nValue = 32; break;
        default: nValue =  0; break;
        }
        UpdateDisplayModeUI(hWnd, lpGameOpts->color_depth, nValue);
    }
}

/* Handle changes to the current display to use */
static void DisplayChange(HWND hWnd)
{
    int nCurSelection;

    nCurSelection = ComboBox_GetCurSel(GetDlgItem(hWnd, IDC_DISPLAYS));
    if (nCurSelection != CB_ERR)
    {
        /* reset modes with the newly selected display */
        DirectDraw_CreateByIndex(nCurSelection);
        UpdateDisplayModeUI(hWnd, lpGameOpts->color_depth, lpGameOpts->screen_depth);
    }
}

/* Handle changes to the Volume slider */
static void VolumeSelectionChange(HWND hWnd)
{
    char buf[100];
    int  nValue;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_VOLUME), TBM_GETPOS, 0, 0);

    /* Set the static display to the new value */
    sprintf(buf, "%ddB", nValue - 32);
    Static_SetText(GetDlgItem(hWnd, IDC_VOLUMEDISP), buf);
}

/* Handle changes to the DirectSound delay frames slider */
static void SoundDelaySelectionChange(HWND hWnd)
{
    char buf[100];
    int  nValue;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_SOUNDDELAY), TBM_GETPOS, 0, 0);

    /* Set the static display to the new value */
    sprintf(buf, "%dframes", nValue + 1);
    Static_SetText(GetDlgItem(hWnd, IDC_SOUNDDELAYDISP), buf);
}

/* Handle changes to the Transparency Rate slider */
static void RateSelectionChange(HWND hWnd)
{
    char buf[100];
    int  nValue;

    /* Get the current value of the control */
    nValue = SendMessage(GetDlgItem(hWnd, IDC_UI_TRANSPARENCY_RATE), TBM_GETPOS, 0, 0);

    /* Set the static display to the new value */
    sprintf(buf, "%d%%", nValue);
    Static_SetText(GetDlgItem(hWnd, IDC_TRANSDISP), buf);
}

/* Adjust possible choices in the Screen Size drop down */
static void UpdateDisplayModeUI(HWND hWnd, DWORD dwDepth, DWORD dwScreenDepth)
{
    int                     i;
    char                    buf[32], old_str[32];
    struct tDisplayModes*   pDisplayModes;
    int                     nPick;
    int                     nCount = 0;
    int                     nSelection = 0;
    DWORD                   w = 0, h = 0, r = 0;
    HWND                    hCtrl = GetDlgItem(hWnd, IDC_SIZES);

    if (!hCtrl)
        return;

#ifdef JAPANESE
    strcpy(old_str, "自動調整");
#else
    strcpy(old_str, "Auto size");
#endif

    /* Find out what is currently selected if anything. */
    nPick = ComboBox_GetCurSel(hCtrl);
    if (nPick != 0 && nPick != CB_ERR)
    {
        ComboBox_GetLBText(GetDlgItem(hWnd, IDC_SIZES), nPick, buf);
        if (sscanf(buf, "%ldx%ld %ldHz", &w, &h, &r) == 3)
            strcpy(old_str, buf);
    }

    /* Auto mode. Find out what depth is ok for this game. */
    if (dwDepth == 0)
    {
        dwDepth = 16;
#if 0 //def SUPPORT_32BPP
        if ((drivers[iGame]->drv->video_attributes & VIDEO_RGB_DIRECT)
        &&  (drivers[iGame]->drv->video_attributes & VIDEO_NEEDS_6BITS_PER_GUN))
            dwDepth = 32;
#endif
    }

    /* Auto mode. Find out what depth is ok for this game. */
    if (dwScreenDepth == 0)
    {
        dwScreenDepth = 16;
#if 0 //def SUPPORT_32BPP
        if ((drivers[iGame]->drv->video_attributes & VIDEO_RGB_DIRECT)
        &&  (drivers[iGame]->drv->video_attributes & VIDEO_NEEDS_6BITS_PER_GUN))
            dwScreenDepth = 32;
#endif
    }

    /* Remove all items in the list. */
    ComboBox_ResetContent(hCtrl);

#ifdef JAPANESE
    ComboBox_AddString(hCtrl, "自動調整");
#else
    ComboBox_AddString(hCtrl, "Auto size");
#endif

    pDisplayModes = DirectDraw_GetDisplayModes();

    for (i = 0; i < pDisplayModes->m_nNumModes; i++)
    {
        if (pDisplayModes->m_Modes[i].m_dwBPP == dwScreenDepth
        ||  (dwScreenDepth == 32 && pDisplayModes->m_Modes[i].m_dwBPP == 24))
        {
            int res, j, addmode;
            char buf1[32], buf2[32];

            sprintf(buf1, "%04ld %04ld %03ld", pDisplayModes->m_Modes[i].m_dwWidth,
                                               pDisplayModes->m_Modes[i].m_dwHeight,
                                               pDisplayModes->m_Modes[i].m_dwRefreshRate);

            addmode = 1; // add

            for (j = 1; j < nCount; j++)
            {
                ComboBox_GetLBText(GetDlgItem(hWnd, IDC_SIZES), j, buf);
                if (sscanf(buf, "%ldx%ld %ldHz", &w, &h, &r) != 3)
                {
                    w = 0;
                    h = 0;
                    r = 0;
                }
                sprintf(buf2, "%04ld %04ld %03ld", w, h, r);

                res = strcmp(buf2, buf1);
                if (res == 0)
                {
                   /* same resolution and same refresh rate */
                   addmode = 0; // skip;
                   break;
                }
                else if (res > 0)
                {
                   /* same resolution and same refresh rate */
                   addmode = 2; // insert;
                   break;
                }
            }

            if (addmode)
            {
                sprintf(buf, "%ldx%ld %ldHz", pDisplayModes->m_Modes[i].m_dwWidth,
                                              pDisplayModes->m_Modes[i].m_dwHeight,
                                              pDisplayModes->m_Modes[i].m_dwRefreshRate);

                if (addmode == 1)
                    ComboBox_AddString(hCtrl, buf);
                else
                    ComboBox_InsertString(hCtrl, j, buf);

                nCount++;
            }
        }
    }

    for (i = 0; i <= nCount; i++)
    {
        ComboBox_GetLBText(GetDlgItem(hWnd, IDC_SIZES), i, buf);
        if (strcmp(old_str, buf) == 0)
        {
            nSelection = i;
            break;
        }
    }

    ComboBox_SetCurSel(hCtrl, nSelection);
}

/* Initialize the Display options to auto mode */
static void InitializeDisplayModeUI(HWND hWnd)
{
    UpdateDisplayModeUI(hWnd, 0, 0);
}

/* Initialize the sound options */
static void InitializeSoundUI(HWND hWnd)
{
    int     sound;
    HWND    hCtrl;

    sound = 0;

    hCtrl = GetDlgItem(hWnd, IDC_SOUNDTYPE);
    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "サウンドなし");
        ComboBox_AddString(hCtrl, "DirectSound (標準)");
#else
        ComboBox_AddString(hCtrl, "No Sound");
        ComboBox_AddString(hCtrl, "DirectSound (default)");
#endif
        ComboBox_AddString(hCtrl, "DirectSound (mamew)");

        ComboBox_SetCurSel(GetDlgItem(hWnd, IDC_SOUNDTYPE), sound);
    }

    hCtrl = GetDlgItem(hWnd, IDC_SAMPLERATE);
    if (hCtrl)
    {
        ComboBox_AddString(hCtrl, "11025");
        ComboBox_AddString(hCtrl, "22050");
        ComboBox_AddString(hCtrl, "44100");
        ComboBox_AddString(hCtrl, "48000");
        ComboBox_SetCurSel(hCtrl, 1);
    }
#if 0
#ifdef MAME_AVI
    hCtrl = GetDlgItem(hWnd, IDC_RECORDING_SAMPLERATE);
    if (hCtrl)
    {
		ComboBox_AddString(hCtrl, "4000");
		ComboBox_AddString(hCtrl, "8000");
        ComboBox_AddString(hCtrl, "11025");
		ComboBox_AddString(hCtrl, "16000");
		ComboBox_AddString(hCtrl, "18900");
        ComboBox_AddString(hCtrl, "22050");
		ComboBox_AddString(hCtrl, "24000");
        ComboBox_AddString(hCtrl, "32000");
		ComboBox_AddString(hCtrl, "37800");
        ComboBox_AddString(hCtrl, "44100");
        ComboBox_AddString(hCtrl, "48000");
		ComboBox_AddString(hCtrl, "64000");
		ComboBox_AddString(hCtrl, "96000");
        ComboBox_SetCurSel(hCtrl, 5);
    }
#endif /* MAME_AVI */
#endif
}

#ifdef MULTI_MONITOR

/* Populate the Display type drop down */
static void InitializeDisplayTypeUI(HWND hWnd)
{
    int i, num;

    HWND hWndDisplays = GetDlgItem(hWnd, IDC_DISPLAYS);

    if (hWndDisplays == 0)
        return;

    num = DirectDraw_GetNumDisplays();

    ComboBox_ResetContent(hWndDisplays);
    if (num == 1)
    {
#ifdef JAPANESE
        ComboBox_AddString(hWndDisplays, "プライマリディスプレイ");
#else
        ComboBox_AddString(hWndDisplays, "Primary Display");
#endif
        ComboBox_SetCurSel(hWndDisplays, 0);
    }
    else
    {
        for (i = 0; i < num; i++)
        {
            ComboBox_AddString(hWndDisplays, DirectDraw_GetDisplayName(i));
        }
    }
}

#else

/* Populate the Display type drop down */
static void InitializeDisplayTypeUI(HWND hWnd)
{
    hWndDisplays = GetDlgItem(hWnd, IDC_DISPLAYS);

    if (hWndDisplays == 0)
        return;

    ComboBox_ResetContent(hWndDisplays);
#ifdef JAPANESE
    ComboBox_AddString(hWndDisplays, "プライマリディスプレイ");
#else
    ComboBox_AddString(hWndDisplays, "Primary Display");
#endif
    ComboBox_SetCurSel(hWndDisplays, 0);
    nNumDisplays++;
}

#endif

/* Populate the Frame Skipping drop down */
static void InitializeSkippingUI(HWND hWnd)
{
    int i;
    char buf[32];
    HWND hCtrl = GetDlgItem(hWnd, IDC_FRAMESKIP);

    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "フレームスキップなし");

        for (i = 1; i < 12; i++)
        {
            sprintf(buf, "12フレームに%d回スキップ", i);
            ComboBox_AddString(hCtrl, buf);
        }
#else
        ComboBox_AddString(hCtrl, "Draw every frame");

        for (i = 1; i < 12; i++)
        {
            sprintf(buf, "Skip %d of every 12 frames", i);
            ComboBox_AddString(hCtrl, buf);
        }
#endif
    }
}

/* Populate the Rotate drop down */
static void InitializeRotateUI(HWND hWnd)
{
    HWND hCtrl = GetDlgItem(hWnd, IDC_ROTATE);

    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "なし");       /* 0 */
        ComboBox_AddString(hCtrl, "時計回り");   /* 1 */
        ComboBox_AddString(hCtrl, "反時計回り"); /* 2 */
#else
        ComboBox_AddString(hCtrl, "None");   /* 0 */
        ComboBox_AddString(hCtrl, "Right");  /* 1 */
        ComboBox_AddString(hCtrl, "Left");   /* 2 */
#endif
    }
}

/* Populate the Color depth drop down */
static void InitializeDepthUI(HWND hWnd)
{
    HWND hCtrl;

    hCtrl = GetDlgItem(hWnd, IDC_DEPTH);
    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "自動");
        ComboBox_AddString(hCtrl, "15/16 bit");
        ComboBox_AddString(hCtrl, "32 bit");
#else
        ComboBox_AddString(hCtrl, "Auto");
        ComboBox_AddString(hCtrl, "15/16 bit");
        ComboBox_AddString(hCtrl, "32 bit");
#endif
    }

    hCtrl = GetDlgItem(hWnd, IDC_SCREENDEPTH);
    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "自動");
#else
        ComboBox_AddString(hCtrl, "Auto");
#endif
        ComboBox_AddString(hCtrl, "15/16 bit");
        ComboBox_AddString(hCtrl, "24 bit");
        ComboBox_AddString(hCtrl, "32 bit");
    }
}

/* Populate the Scanline Brightness drop down */
static void InitializeScanlineBrightnessUI(HWND hWnd)
{
    HWND hCtrl = GetDlgItem(hWnd, IDC_SLBRIGHT);

    if (hCtrl)
    {
        ComboBox_AddString(hCtrl, "0%");
        ComboBox_AddString(hCtrl, "25%");
        ComboBox_AddString(hCtrl, "50%");
        ComboBox_AddString(hCtrl, "75%");
    }
}

/* Populate the Stretch Scale drop down */
static void InitializeStretchScaleUI(HWND hWnd)
{
    HWND hCtrl = GetDlgItem(hWnd, IDC_STRETCHSCALE);

    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "2倍\x95\x5c示");
        ComboBox_AddString(hCtrl, "3倍\x95\x5c示");
        ComboBox_AddString(hCtrl, "4倍\x95\x5c示");
#else
        ComboBox_AddString(hCtrl, "Stretch x2");
        ComboBox_AddString(hCtrl, "Stretch x3");
        ComboBox_AddString(hCtrl, "Stretch x4");
#endif
    }
}

/* Populate the Default Input drop down */
static void InitializeDefaultInputUI(HWND hWnd)
{
    HWND hCtrl = GetDlgItem(hWnd, IDC_DEFAULT_INPUT);

    if (hCtrl)
    {
#ifdef JAPANESE
        ComboBox_AddString(hCtrl, "標準");
        ComboBox_AddString(hCtrl, "HotRod用");
        ComboBox_AddString(hCtrl, "HotRod SE用");
#else
        ComboBox_AddString(hCtrl, "Standard");
        ComboBox_AddString(hCtrl, "HotRod");
        ComboBox_AddString(hCtrl, "HotRod SE");
#endif
    }
}

#ifdef NEOGEO_BIOS_SELECT
static void InitializeBiosUI(HWND hwnd)
{
	HWND hCtrl = GetDlgItem(hwnd, IDC_BIOSTYPE);

	if (hCtrl)
	{
		int i;
		for (i = 0; i < NEOGEO_BIOS_MAX; i++)
			ComboBox_AddString(hCtrl, neogeo_bios[i].desc);
	}
}
#endif /* NEOGEO_BIOS_SELECT */

/* Populate the Joystick ID drop down */
static void InitializeJoyidUI(HWND hWnd)
{
    HWND hCtrl;
    int i, j;
    char buf[8];

    for (i = 0; i < 4; i++)
    {
        hCtrl = GetDlgItem(hWnd, IDC_JOYID1 + i);
        if (hCtrl)
        {
            for (j = 0;j < 8; j++)
            {
                sprintf(buf, "ID:%d", j + 1);
                ComboBox_AddString(hCtrl, buf);
            }
        }
    }
}

/**************************************************************************
    Game History functions
 **************************************************************************/

/* Load indexes from history.dat if found */
char *GameHistory(int game_index)
{
    historyBuf[0] = '\0';

    if (load_driver_history(drivers[game_index], historyBuf, sizeof(historyBuf)) == 0)
        HistoryFixBuf(historyBuf);

    return historyBuf;
}

static void HistoryFixBuf(char *buf)
{
    char *s  = tempHistoryBuf;
    char *p  = buf;
    int  len = 0;

    if (strlen(buf) < 3)
    {
        *buf = '\0';
        return;
    }

    while (*p && len < MAX_HISTORY_LEN - 1)
    {
        if (*p == '\n')
        {
            *s++ = '\r';
            len++;
        }

        *s++ = *p++;
        len++;
    }

    *s++ = '\0';
    strcpy(buf, tempHistoryBuf);
}

/* End of source file */
