Files
86Box/src/win/win_settings.c
Jasmine Iwanek 9c05a30cb7 Merge pull request #3439 from lemondrops/bugger-fix
Fix ISABugger not being actually disabled on machines without ISA
2023-07-01 08:39:17 -04:00

5694 lines
213 KiB
C

/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Windows 86Box Settings dialog handler.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* David Hrdlička, <hrdlickadavid@outlook.com>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2016-2019 Miran Grca.
* Copyright 2018-2019 David Hrdlička.
* Copyright 2021 Laci bá'
* Copyright 2021-2023 Jasmine Iwanek.
*/
#define UNICODE
#define BITMAP WINDOWS_BITMAP
#include <windows.h>
#include <windowsx.h>
#include <uxtheme.h>
#undef BITMAP
#ifdef ENABLE_SETTINGS_LOG
# include <assert.h>
#endif
#include <commctrl.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/config.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
#include <86box/nvr.h>
#include <86box/machine.h>
#include <86box/gameport.h>
#include <86box/isamem.h>
#include <86box/isartc.h>
#include <86box/lpt.h>
#include <86box/mouse.h>
#include <86box/serial.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/hdd.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/zip.h>
#include <86box/mo.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/thread.h>
#include <86box/network.h>
#include <86box/sound.h>
#include <86box/midi.h>
#include <86box/snd_mpu401.h>
#include <86box/snd_opl.h>
#include <86box/video.h>
#include <86box/vid_xga_device.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/win.h>
#include <86box/serial_passthrough.h>
#include "../disk/minivhd/minivhd.h"
/* Icon, Bus, File, C, H, S, Size, Speed */
#define C_COLUMNS_HARD_DISKS 7
#define C_COLUMNS_FLOPPY_DRIVES 3
#define C_COLUMNS_CDROM_DRIVES 3
#define C_COLUMNS_MO_DRIVES 2
#define C_COLUMNS_ZIP_DRIVES 2
static int first_cat = 0;
/* Machine category */
static int temp_machine_type;
static int temp_machine;
static int temp_cpu;
static int temp_wait_states;
static int temp_fpu;
static int temp_sync;
static cpu_family_t *temp_cpu_f;
static uint32_t temp_mem_size;
#ifdef USE_DYNAREC
static int temp_dynarec;
#endif
static int temp_fpu_softfloat;
/* Video category */
static int temp_gfxcard[2];
static int temp_ibm8514;
static int temp_voodoo;
static int temp_xga;
/* Input devices category */
static int temp_mouse;
static int temp_joystick;
/* Sound category */
static int temp_sound_card[SOUND_CARD_MAX];
static int temp_midi_output_device;
static int temp_midi_input_device;
static int temp_mpu401;
static int temp_float;
static int temp_fm_driver;
/* Network category */
static int temp_net_type[NET_CARD_MAX];
static uint16_t temp_net_card[NET_CARD_MAX];
static char temp_pcap_dev[NET_CARD_MAX][128];
/* Ports category */
static int temp_lpt_devices[PARALLEL_MAX];
static uint8_t temp_serial[SERIAL_MAX];
static uint8_t temp_lpt[PARALLEL_MAX];
static int temp_serial_passthrough_enabled[SERIAL_MAX];
/* Other peripherals category */
static int temp_fdc_card;
static int temp_hdc;
static int temp_ide_ter;
static int temp_ide_qua;
static int temp_cassette;
static int temp_scsi_card[SCSI_BUS_MAX];
static int temp_bugger;
static int temp_postcard;
static int temp_isartc;
static int temp_isamem[ISAMEM_MAX];
static uint8_t temp_deviceconfig;
/* Hard disks category */
static hard_disk_t temp_hdd[HDD_NUM];
/* Floppy drives category */
static int temp_fdd_types[FDD_NUM];
static int temp_fdd_turbo[FDD_NUM];
static int temp_fdd_check_bpb[FDD_NUM];
/* Other removable devices category */
static cdrom_t temp_cdrom[CDROM_NUM];
static zip_drive_t temp_zip_drives[ZIP_NUM];
static mo_drive_t temp_mo_drives[MO_NUM];
static HWND hwndParentDialog;
static HWND hwndChildDialog;
static uint32_t displayed_category = 0;
extern int is486;
static int listtomachinetype[256];
static int listtomachine[256];
static int listtocpufamily[256];
static int listtocpu[256];
static int settings_list_to_device[2][256];
static int settings_list_to_fdc[20];
static int settings_list_to_midi[20];
static int settings_list_to_midi_in[20];
static int settings_list_to_hdc[20];
static int max_spt = 63;
static int max_hpc = 255;
static int max_tracks = 266305;
static uint64_t mfm_tracking;
static uint64_t esdi_tracking;
static uint64_t xta_tracking;
static uint64_t ide_tracking;
static uint64_t scsi_tracking[8];
static uint64_t size;
static int hd_listview_items;
static int hdc_id_to_listview_index[HDD_NUM];
static int no_update = 0;
static int existing = 0;
static int chs_enabled = 0;
static int lv1_current_sel;
static int lv2_current_sel;
static int hard_disk_added = 0;
static int next_free_id = 0;
static int selection = 127;
static int spt;
static int hpc;
static int tracks;
static int ignore_change = 0;
static hard_disk_t new_hdd;
static hard_disk_t *hdd_ptr;
static wchar_t hd_file_name[512];
static WCHAR device_name[512];
static int
settings_get_check(HWND hdlg, int id)
{
return SendMessage(GetDlgItem(hdlg, id), BM_GETCHECK, 0, 0);
}
static int
settings_get_cur_sel(HWND hdlg, int id)
{
return SendMessage(GetDlgItem(hdlg, id), CB_GETCURSEL, 0, 0);
}
static void
settings_set_check(HWND hdlg, int id, int val)
{
SendMessage(GetDlgItem(hdlg, id), BM_SETCHECK, val, 0);
}
static void
settings_set_cur_sel(HWND hdlg, int id, int val)
{
SendMessage(GetDlgItem(hdlg, id), CB_SETCURSEL, val, 0);
}
static void
settings_reset_content(HWND hdlg, int id)
{
SendMessage(GetDlgItem(hdlg, id), CB_RESETCONTENT, 0, 0);
}
static void
settings_add_string(HWND hdlg, int id, LPARAM string)
{
SendMessage(GetDlgItem(hdlg, id), CB_ADDSTRING, 0, string);
}
static void
settings_enable_window(HWND hdlg, int id, int condition)
{
EnableWindow(GetDlgItem(hdlg, id), condition ? TRUE : FALSE);
}
static void
settings_show_window(HWND hdlg, int id, int condition)
{
HWND h;
h = GetDlgItem(hdlg, id);
EnableWindow(h, condition ? TRUE : FALSE);
ShowWindow(h, condition ? SW_SHOW : SW_HIDE);
}
static void
settings_listview_enable_styles(HWND hdlg, int id)
{
HWND h;
h = GetDlgItem(hdlg, id);
SetWindowTheme(h, L"Explorer", NULL);
ListView_SetExtendedListViewStyle(h, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
}
static void
settings_listview_select(HWND hdlg, int id, int selection)
{
HWND h;
h = GetDlgItem(hdlg, id);
ListView_SetItemState(h, selection, LVIS_FOCUSED | LVIS_SELECTED, 0x000F);
}
static void
settings_process_messages(void)
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
static BOOL
image_list_init(HWND hdlg, int id, const uint8_t *icon_ids)
{
HICON hiconItem;
HIMAGELIST hSmall;
HWND hwndList = GetDlgItem(hdlg, id);
int i = 0;
hSmall = ListView_GetImageList(hwndList, LVSIL_SMALL);
if (hSmall != 0)
ImageList_Destroy(hSmall);
hSmall = ImageList_Create(win_get_system_metrics(SM_CXSMICON, dpi),
win_get_system_metrics(SM_CYSMICON, dpi),
ILC_MASK | ILC_COLOR32, 1, 1);
while (1) {
if (icon_ids[i] == 0)
break;
hiconItem = hIcon[icon_ids[i]];
ImageList_AddIcon(hSmall, hiconItem);
i++;
}
ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL);
return TRUE;
}
/* Show a MessageBox dialog. This is nasty, I know. --FvK */
static int
settings_msgbox_header(int flags, void *header, void *message)
{
HWND h;
int i;
h = hwndMain;
hwndMain = hwndParentDialog;
i = ui_msgbox_header(flags, header, message);
hwndMain = h;
return i;
}
static int
settings_msgbox_ex(int flags, void *header, void *message, void *btn1, void *btn2, void *btn3)
{
HWND h;
int i;
h = hwndMain;
hwndMain = hwndParentDialog;
i = ui_msgbox_ex(flags, header, message, btn1, btn2, btn3);
hwndMain = h;
return i;
}
/* This does the initial read of global variables into the temporary ones. */
static void
win_settings_init(void)
{
int i = 0;
/* Machine category */
temp_machine_type = machine_get_type(machine);
temp_machine = machine;
temp_cpu_f = cpu_f;
temp_wait_states = cpu_waitstates;
temp_cpu = cpu;
temp_mem_size = mem_size;
#ifdef USE_DYNAREC
temp_dynarec = cpu_use_dynarec;
#endif
temp_fpu_softfloat = fpu_softfloat;
temp_fpu = fpu_type;
temp_sync = time_sync;
/* Video category */
temp_gfxcard[0] = gfxcard[0];
temp_gfxcard[1] = gfxcard[1];
temp_voodoo = voodoo_enabled;
temp_ibm8514 = ibm8514_enabled;
temp_xga = xga_enabled;
/* Input devices category */
temp_mouse = mouse_type;
temp_joystick = joystick_type;
/* Sound category */
for (i = 0; i < SOUND_CARD_MAX; i++)
temp_sound_card[i] = sound_card_current[i];
temp_midi_output_device = midi_output_device_current;
temp_midi_input_device = midi_input_device_current;
temp_mpu401 = mpu401_standalone_enable;
temp_float = sound_is_float;
temp_fm_driver = fm_driver;
/* Network category */
for (i = 0; i < NET_CARD_MAX; i++) {
temp_net_type[i] = net_cards_conf[i].net_type;
memset(temp_pcap_dev[i], 0, sizeof(temp_pcap_dev[i]));
#ifdef ENABLE_SETTINGS_LOG
assert(sizeof(temp_pcap_dev[i]) == sizeof(net_cards_conf[i].host_dev_name));
#endif
memcpy(temp_pcap_dev[i], net_cards_conf[i].host_dev_name, sizeof(net_cards_conf[i].host_dev_name));
temp_net_card[i] = net_cards_conf[i].device_num;
}
/* Ports category */
for (i = 0; i < PARALLEL_MAX; i++) {
temp_lpt_devices[i] = lpt_ports[i].device;
temp_lpt[i] = lpt_ports[i].enabled;
}
for (i = 0; i < SERIAL_MAX; i++) {
temp_serial[i] = com_ports[i].enabled;
temp_serial_passthrough_enabled[i] = serial_passthrough_enabled[i];
}
/* Storage devices category */
for (i = 0; i < SCSI_BUS_MAX; i++)
temp_scsi_card[i] = scsi_card_current[i];
temp_fdc_card = fdc_type;
temp_hdc = hdc_current;
temp_ide_ter = ide_ter_enabled;
temp_ide_qua = ide_qua_enabled;
temp_cassette = cassette_enable;
mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0;
for (i = 0; i < SCSI_LUN_MAX; i++)
scsi_tracking[i] = 0;
/* Hard disks category */
memcpy(temp_hdd, hdd, HDD_NUM * sizeof(hard_disk_t));
for (i = 0; i < HDD_NUM; i++) {
if (hdd[i].bus == HDD_BUS_MFM)
mfm_tracking |= (1 << (hdd[i].mfm_channel << 3));
else if (hdd[i].bus == HDD_BUS_XTA)
xta_tracking |= (1 << (hdd[i].xta_channel << 3));
else if (hdd[i].bus == HDD_BUS_ESDI)
esdi_tracking |= (1 << (hdd[i].esdi_channel << 3));
else if ((hdd[i].bus == HDD_BUS_IDE) || (hdd[i].bus == HDD_BUS_ATAPI))
ide_tracking |= (1 << (hdd[i].ide_channel << 3));
else if (hdd[i].bus == HDD_BUS_SCSI)
scsi_tracking[hdd[i].scsi_id >> 3] |= (1 << ((hdd[i].scsi_id & 0x07) << 3));
}
/* Floppy drives category */
for (i = 0; i < FDD_NUM; i++) {
temp_fdd_types[i] = fdd_get_type(i);
temp_fdd_turbo[i] = fdd_get_turbo(i);
temp_fdd_check_bpb[i] = fdd_get_check_bpb(i);
}
/* Other removable devices category */
memcpy(temp_cdrom, cdrom, CDROM_NUM * sizeof(cdrom_t));
for (i = 0; i < CDROM_NUM; i++) {
if (cdrom[i].bus_type == CDROM_BUS_ATAPI)
ide_tracking |= (2 << (cdrom[i].ide_channel << 3));
else if (cdrom[i].bus_type == CDROM_BUS_SCSI)
scsi_tracking[cdrom[i].scsi_device_id >> 3] |= (1 << ((cdrom[i].scsi_device_id & 0x07) << 3));
}
memcpy(temp_zip_drives, zip_drives, ZIP_NUM * sizeof(zip_drive_t));
for (i = 0; i < ZIP_NUM; i++) {
if (zip_drives[i].bus_type == ZIP_BUS_ATAPI)
ide_tracking |= (4 << (zip_drives[i].ide_channel << 3));
else if (zip_drives[i].bus_type == ZIP_BUS_SCSI)
scsi_tracking[zip_drives[i].scsi_device_id >> 3] |= (1 << ((zip_drives[i].scsi_device_id & 0x07) << 3));
}
memcpy(temp_mo_drives, mo_drives, MO_NUM * sizeof(mo_drive_t));
for (i = 0; i < MO_NUM; i++) {
if (mo_drives[i].bus_type == MO_BUS_ATAPI)
ide_tracking |= (1 << (mo_drives[i].ide_channel << 3));
else if (mo_drives[i].bus_type == MO_BUS_SCSI)
scsi_tracking[mo_drives[i].scsi_device_id >> 3] |= (1 << ((mo_drives[i].scsi_device_id & 0x07) << 3));
}
/* Other peripherals category */
temp_bugger = bugger_enabled;
temp_postcard = postcard_enabled;
temp_isartc = isartc_type;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
temp_isamem[i] = isamem_type[i];
temp_deviceconfig = 0;
}
/* This returns 1 if any variable has changed, 0 if not. */
static int
win_settings_changed(void)
{
int i = 0;
/* Machine category */
i = i || (machine != temp_machine);
i = i || (cpu_f != temp_cpu_f);
i = i || (cpu_waitstates != temp_wait_states);
i = i || (cpu != temp_cpu);
i = i || (mem_size != temp_mem_size);
#ifdef USE_DYNAREC
i = i || (temp_dynarec != cpu_use_dynarec);
#endif
i = i || (temp_fpu_softfloat != fpu_softfloat);
i = i || (temp_fpu != fpu_type);
i = i || (temp_sync != time_sync);
/* Video category */
i = i || (gfxcard[0] != temp_gfxcard[0]);
i = i || (gfxcard[1] != temp_gfxcard[1]);
i = i || (voodoo_enabled != temp_voodoo);
i = i || (ibm8514_enabled != temp_ibm8514);
i = i || (xga_enabled != temp_xga);
/* Input devices category */
i = i || (mouse_type != temp_mouse);
i = i || (joystick_type != temp_joystick);
/* Sound category */
for (uint8_t j = 0; j < SOUND_CARD_MAX; j++)
i = i || (sound_card_current[j] != temp_sound_card[j]);
i = i || (midi_output_device_current != temp_midi_output_device);
i = i || (midi_input_device_current != temp_midi_input_device);
i = i || (mpu401_standalone_enable != temp_mpu401);
i = i || (sound_is_float != temp_float);
i = i || (fm_driver != temp_fm_driver);
/* Network category */
for (uint8_t j = 0; j < NET_CARD_MAX; j++) {
i = i || (net_cards_conf[j].net_type != temp_net_type[j]);
i = i || strcmp(temp_pcap_dev[j], net_cards_conf[j].host_dev_name);
i = i || (net_cards_conf[j].device_num != temp_net_card[j]);
}
/* Ports category */
for (uint8_t j = 0; j < PARALLEL_MAX; j++) {
i = i || (temp_lpt_devices[j] != lpt_ports[j].device);
i = i || (temp_lpt[j] != lpt_ports[j].enabled);
}
for (uint8_t j = 0; j < SERIAL_MAX; j++) {
i = i || (temp_serial[j] != com_ports[j].enabled);
i = i || (temp_serial_passthrough_enabled[i] != serial_passthrough_enabled[i]);
}
/* Storage devices category */
for (uint8_t j = 0; j < SCSI_BUS_MAX; j++)
i = i || (temp_scsi_card[j] != scsi_card_current[j]);
i = i || (fdc_type != temp_fdc_card);
i = i || (hdc_current != temp_hdc);
i = i || (temp_ide_ter != ide_ter_enabled);
i = i || (temp_ide_qua != ide_qua_enabled);
i = i || (temp_cassette != cassette_enable);
/* Hard disks category */
i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
/* Floppy drives category */
for (uint8_t j = 0; j < FDD_NUM; j++) {
i = i || (temp_fdd_types[j] != fdd_get_type(j));
i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j));
i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j));
}
/* Other removable devices category */
i = i || memcmp(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t));
i = i || memcmp(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t));
i = i || memcmp(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t));
/* Other peripherals category */
i = i || (temp_bugger != bugger_enabled);
i = i || (temp_postcard != postcard_enabled);
i = i || (temp_isartc != isartc_type);
/* ISA memory boards. */
for (uint8_t j = 0; j < ISAMEM_MAX; j++)
i = i || (temp_isamem[j] != isamem_type[j]);
i = i || !!temp_deviceconfig;
return i;
}
/* This saves the settings back to the global variables. */
static void
win_settings_save(void)
{
pc_reset_hard_close();
/* Machine category */
machine = temp_machine;
cpu_f = temp_cpu_f;
cpu_waitstates = temp_wait_states;
cpu = temp_cpu;
mem_size = temp_mem_size;
#ifdef USE_DYNAREC
cpu_use_dynarec = temp_dynarec;
#endif
fpu_softfloat = temp_fpu_softfloat;
fpu_type = temp_fpu;
time_sync = temp_sync;
/* Video category */
gfxcard[0] = temp_gfxcard[0];
gfxcard[1] = temp_gfxcard[1];
voodoo_enabled = temp_voodoo;
ibm8514_enabled = temp_ibm8514;
xga_enabled = temp_xga;
/* Input devices category */
mouse_type = temp_mouse;
joystick_type = temp_joystick;
/* Sound category */
for (uint8_t i = 0; i < SOUND_CARD_MAX; i++)
sound_card_current[i] = temp_sound_card[i];
midi_output_device_current = temp_midi_output_device;
midi_input_device_current = temp_midi_input_device;
mpu401_standalone_enable = temp_mpu401;
sound_is_float = temp_float;
fm_driver = temp_fm_driver;
/* Network category */
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
net_cards_conf[i].net_type = temp_net_type[i];
memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name));
strcpy(net_cards_conf[i].host_dev_name, temp_pcap_dev[i]);
net_cards_conf[i].device_num = temp_net_card[i];
}
/* Ports category */
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
lpt_ports[i].device = temp_lpt_devices[i];
lpt_ports[i].enabled = temp_lpt[i];
}
for (uint8_t i = 0; i < SERIAL_MAX; i++) {
com_ports[i].enabled = temp_serial[i];
serial_passthrough_enabled[i] = temp_serial_passthrough_enabled[i];
}
/* Storage devices category */
for (uint8_t i = 0; i < SCSI_BUS_MAX; i++)
scsi_card_current[i] = temp_scsi_card[i];
hdc_current = temp_hdc;
fdc_type = temp_fdc_card;
ide_ter_enabled = temp_ide_ter;
ide_qua_enabled = temp_ide_qua;
cassette_enable = temp_cassette;
/* Hard disks category */
memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
for (uint8_t i = 0; i < HDD_NUM; i++)
hdd[i].priv = NULL;
/* Floppy drives category */
for (uint8_t i = 0; i < FDD_NUM; i++) {
fdd_set_type(i, temp_fdd_types[i]);
fdd_set_turbo(i, temp_fdd_turbo[i]);
fdd_set_check_bpb(i, temp_fdd_check_bpb[i]);
}
/* Removable devices category */
memcpy(cdrom, temp_cdrom, CDROM_NUM * sizeof(cdrom_t));
for (uint8_t i = 0; i < CDROM_NUM; i++) {
cdrom[i].is_dir = 0;
cdrom[i].priv = NULL;
cdrom[i].ops = NULL;
cdrom[i].image = NULL;
cdrom[i].insert = NULL;
cdrom[i].close = NULL;
cdrom[i].get_volume = NULL;
cdrom[i].get_channel = NULL;
}
memcpy(zip_drives, temp_zip_drives, ZIP_NUM * sizeof(zip_drive_t));
for (uint8_t i = 0; i < ZIP_NUM; i++) {
zip_drives[i].f = NULL;
zip_drives[i].priv = NULL;
}
memcpy(mo_drives, temp_mo_drives, MO_NUM * sizeof(mo_drive_t));
for (uint8_t i = 0; i < MO_NUM; i++) {
mo_drives[i].f = NULL;
mo_drives[i].priv = NULL;
}
/* Other peripherals category */
bugger_enabled = temp_bugger;
postcard_enabled = temp_postcard;
isartc_type = temp_isartc;
/* ISA memory boards. */
for (uint8_t i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = temp_isamem[i];
/* Mark configuration as changed. */
config_changed = 2;
pc_reset_hard_init();
}
static void
win_settings_machine_recalc_fpu(HWND hdlg)
{
int c;
int type;
LPTSTR lptsTemp;
const char *stransi;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
settings_reset_content(hdlg, IDC_COMBO_FPU);
c = 0;
while (1) {
stransi = (char *) fpu_get_name_from_index(temp_cpu_f, temp_cpu, c);
type = fpu_get_type_from_index(temp_cpu_f, temp_cpu, c);
if (!stransi)
break;
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_FPU, (LPARAM) (LPCSTR) lptsTemp);
if (!c || (type == temp_fpu))
settings_set_cur_sel(hdlg, IDC_COMBO_FPU, c);
c++;
}
settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, temp_fpu_softfloat);
settings_enable_window(hdlg, IDC_COMBO_FPU, c > 1);
temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu, settings_get_cur_sel(hdlg, IDC_COMBO_FPU));
}
static void
win_settings_machine_recalc_cpu(HWND hdlg)
{
int cpu_type;
#ifdef USE_DYNAREC
int cpu_flags;
#endif
cpu_type = temp_cpu_f->cpus[temp_cpu].cpu_type;
settings_enable_window(hdlg, IDC_COMBO_WS, (cpu_type >= CPU_286) && (cpu_type <= CPU_386DX));
#ifdef USE_DYNAREC
cpu_flags = temp_cpu_f->cpus[temp_cpu].cpu_flags;
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC))
fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n");
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) {
if (!(cpu_flags & CPU_SUPPORTS_DYNAREC))
temp_dynarec = 0;
if (cpu_flags & CPU_REQUIRES_DYNAREC)
temp_dynarec = 1;
settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec);
settings_enable_window(hdlg, IDC_CHECK_DYNAREC, FALSE);
} else {
settings_set_check(hdlg, IDC_CHECK_DYNAREC, temp_dynarec);
settings_enable_window(hdlg, IDC_CHECK_DYNAREC, TRUE);
}
#endif
win_settings_machine_recalc_fpu(hdlg);
}
static void
win_settings_machine_recalc_cpu_m(HWND hdlg)
{
int c;
int i;
int first_eligible = -1;
int current_eligible = 0;
int last_eligible = 0;
LPTSTR lptsTemp;
char *stransi;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
settings_reset_content(hdlg, IDC_COMBO_CPU_SPEED);
c = i = 0;
while (temp_cpu_f->cpus[c].cpu_type != 0) {
if (cpu_is_eligible(temp_cpu_f, c, temp_machine)) {
stransi = (char *) temp_cpu_f->cpus[c].name;
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_CPU_SPEED, (LPARAM) (LPCSTR) lptsTemp);
if (first_eligible == -1)
first_eligible = i;
if (temp_cpu == c)
current_eligible = i;
last_eligible = i;
listtocpu[i++] = c;
}
c++;
}
if (i == 0)
fatal("No eligible CPUs for the selected family\n");
settings_enable_window(hdlg, IDC_COMBO_CPU_SPEED, i != 1);
if (current_eligible < first_eligible)
current_eligible = first_eligible;
else if (current_eligible > last_eligible)
current_eligible = last_eligible;
temp_cpu = listtocpu[current_eligible];
settings_set_cur_sel(hdlg, IDC_COMBO_CPU_SPEED, current_eligible);
win_settings_machine_recalc_cpu(hdlg);
free(lptsTemp);
}
static void
win_settings_machine_recalc_machine(HWND hdlg)
{
HWND h;
int c;
int i;
int current_eligible;
LPTSTR lptsTemp;
char *stransi;
UDACCEL accel;
device_t *d;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
d = (device_t *) machine_get_device(temp_machine);
settings_enable_window(hdlg, IDC_CONFIGURE_MACHINE, d && d->config);
settings_reset_content(hdlg, IDC_COMBO_CPU_TYPE);
c = i = 0;
current_eligible = -1;
while (cpu_families[c].package != 0) {
if (cpu_family_is_eligible(&cpu_families[c], temp_machine)) {
stransi = malloc(strlen((char *) cpu_families[c].manufacturer) + strlen((char *) cpu_families[c].name) + 2);
sprintf(stransi, "%s %s", (char *) cpu_families[c].manufacturer, (char *) cpu_families[c].name);
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
free(stransi);
settings_add_string(hdlg, IDC_COMBO_CPU_TYPE, (LPARAM) (LPCSTR) lptsTemp);
if (&cpu_families[c] == temp_cpu_f)
current_eligible = i;
listtocpufamily[i++] = c;
}
c++;
}
if (i == 0)
fatal("No eligible CPU families for the selected machine\n");
settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, TRUE);
if (current_eligible == -1) {
temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[0]];
settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, 0);
} else {
settings_set_cur_sel(hdlg, IDC_COMBO_CPU_TYPE, current_eligible);
}
settings_enable_window(hdlg, IDC_COMBO_CPU_TYPE, i != 1);
win_settings_machine_recalc_cpu_m(hdlg);
if (machine_get_ram_granularity(temp_machine) & 1023) {
/* KB granularity */
h = GetDlgItem(hdlg, IDC_MEMSPIN);
SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 16) | machine_get_max_ram(temp_machine));
accel.nSec = 0;
accel.nInc = machine_get_ram_granularity(temp_machine);
SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel);
SendMessage(h, UDM_SETPOS, 0, temp_mem_size);
h = GetDlgItem(hdlg, IDC_TEXT_MB);
SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_KB));
} else {
/* MB granularity */
h = GetDlgItem(hdlg, IDC_MEMSPIN);
SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 6) | (machine_get_max_ram(temp_machine) >> 10));
accel.nSec = 0;
accel.nInc = machine_get_ram_granularity(temp_machine) >> 10;
SendMessage(h, UDM_SETACCEL, 1, (LPARAM) &accel);
SendMessage(h, UDM_SETPOS, 0, temp_mem_size >> 10);
h = GetDlgItem(hdlg, IDC_TEXT_MB);
SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_MB));
}
settings_enable_window(hdlg, IDC_MEMSPIN, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine));
settings_enable_window(hdlg, IDC_MEMTEXT, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine));
free(lptsTemp);
}
static char *
machine_type_get_internal_name(int id)
{
if (id < MACHINE_TYPE_MAX)
return "";
else
return NULL;
}
int
machine_type_available(int id)
{
int c = 0;
if ((id > 0) && (id < MACHINE_TYPE_MAX)) {
while (machine_get_internal_name_ex(c) != NULL) {
if (machine_available(c) && (machine_get_type(c) == id))
return 1;
c++;
}
}
return 0;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND h;
HWND h2;
int c;
int d;
int old_machine_type;
LPTSTR lptsTemp;
char *stransi;
switch (message) {
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_MACHINE_TYPE);
memset(listtomachinetype, 0x00, sizeof(listtomachinetype));
while (machine_type_get_internal_name(c) != NULL) {
if (machine_type_available(c)) {
stransi = (char *) machine_types[c].name;
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_MACHINE_TYPE, (LPARAM) lptsTemp);
listtomachinetype[d] = c;
if (c == temp_machine_type)
settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE_TYPE, d);
d++;
}
c++;
}
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_MACHINE);
memset(listtomachine, 0x00, sizeof(listtomachine));
while (machine_get_internal_name_ex(c) != NULL) {
if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) {
stransi = machine_getname_ex(c);
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp);
listtomachine[d] = c;
if (c == temp_machine)
settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, d);
d++;
}
c++;
}
settings_add_string(hdlg, IDC_COMBO_WS, win_get_string(IDS_DEFAULT));
for (c = 0; c < 8; c++) { /* TODO */
wsprintf(lptsTemp, plat_get_string(IDS_WS), c);
settings_add_string(hdlg, IDC_COMBO_WS, (LPARAM) lptsTemp);
}
settings_set_cur_sel(hdlg, IDC_COMBO_WS, temp_wait_states);
#ifdef USE_DYNAREC
settings_set_check(hdlg, IDC_CHECK_DYNAREC, 0);
#endif
settings_set_check(hdlg, IDC_CHECK_SOFTFLOAT, 0);
h = GetDlgItem(hdlg, IDC_MEMSPIN);
h2 = GetDlgItem(hdlg, IDC_MEMTEXT);
SendMessage(h, UDM_SETBUDDY, (WPARAM) h2, 0);
if (temp_sync & TIME_SYNC_ENABLED) {
if (temp_sync & TIME_SYNC_UTC)
settings_set_check(hdlg, IDC_RADIO_TS_UTC, BST_CHECKED);
else
settings_set_check(hdlg, IDC_RADIO_TS_LOCAL, BST_CHECKED);
} else
settings_set_check(hdlg, IDC_RADIO_TS_DISABLED, BST_CHECKED);
win_settings_machine_recalc_machine(hdlg);
free(lptsTemp);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_COMBO_MACHINE_TYPE:
if (HIWORD(wParam) == CBN_SELCHANGE) {
old_machine_type = temp_machine_type;
temp_machine_type = listtomachinetype[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE_TYPE)];
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
settings_reset_content(hdlg, IDC_COMBO_MACHINE);
c = d = 0;
memset(listtomachine, 0x00, sizeof(listtomachine));
while (machine_get_internal_name_ex(c) != NULL) {
if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) {
stransi = machine_getname_ex(c);
mbstowcs(lptsTemp, stransi, strlen(stransi) + 1);
settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp);
listtomachine[d] = c;
if (c == temp_machine)
settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, d);
d++;
}
c++;
}
if (old_machine_type != temp_machine_type) {
settings_set_cur_sel(hdlg, IDC_COMBO_MACHINE, 0);
temp_machine = listtomachine[0];
win_settings_machine_recalc_machine(hdlg);
}
free(lptsTemp);
}
break;
case IDC_COMBO_MACHINE:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)];
win_settings_machine_recalc_machine(hdlg);
}
break;
case IDC_COMBO_CPU_TYPE:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_cpu_f = (cpu_family_t *) &cpu_families[listtocpufamily[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_TYPE)]];
temp_cpu = 0;
win_settings_machine_recalc_cpu_m(hdlg);
}
break;
case IDC_COMBO_CPU_SPEED:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_cpu = listtocpu[settings_get_cur_sel(hdlg, IDC_COMBO_CPU_SPEED)];
win_settings_machine_recalc_cpu(hdlg);
}
break;
case IDC_COMBO_FPU:
if (HIWORD(wParam) == CBN_SELCHANGE) {
temp_fpu = fpu_get_type_from_index(temp_cpu_f, temp_cpu,
settings_get_cur_sel(hdlg, IDC_COMBO_FPU));
}
break;
case IDC_CONFIGURE_MACHINE:
temp_machine = listtomachine[settings_get_cur_sel(hdlg, IDC_COMBO_MACHINE)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) machine_get_device(temp_machine));
break;
}
return FALSE;
case WM_SAVESETTINGS:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
stransi = (char *) malloc(512);
#ifdef USE_DYNAREC
temp_dynarec = settings_get_check(hdlg, IDC_CHECK_DYNAREC);
#endif
temp_fpu_softfloat = settings_get_check(hdlg, IDC_CHECK_SOFTFLOAT);
if (settings_get_check(hdlg, IDC_RADIO_TS_DISABLED))
temp_sync = TIME_SYNC_DISABLED;
if (settings_get_check(hdlg, IDC_RADIO_TS_LOCAL))
temp_sync = TIME_SYNC_ENABLED;
if (settings_get_check(hdlg, IDC_RADIO_TS_UTC))
temp_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC;
temp_wait_states = settings_get_cur_sel(hdlg, IDC_COMBO_WS);
h = GetDlgItem(hdlg, IDC_MEMTEXT);
SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp);
wcstombs(stransi, lptsTemp, 512);
sscanf(stransi, "%u", &temp_mem_size);
if (!(machine_get_ram_granularity(temp_machine) & 1023))
temp_mem_size = temp_mem_size << 10;
temp_mem_size &= ~(machine_get_ram_granularity(temp_machine) - 1);
if (temp_mem_size < machine_get_min_ram(temp_machine))
temp_mem_size = machine_get_min_ram(temp_machine);
else if (temp_mem_size > machine_get_max_ram(temp_machine))
temp_mem_size = machine_get_max_ram(temp_machine);
free(stransi);
free(lptsTemp);
default:
return FALSE;
}
return FALSE;
}
static void
generate_device_name(const device_t *device, char *internal_name, int bus)
{
char temp[512];
WCHAR *wtemp;
memset(device_name, 0x00, 512 * sizeof(WCHAR));
memset(temp, 0x00, 512);
if (!strcmp(internal_name, "none")) {
/* Translate "None". */
wtemp = (WCHAR *) win_get_string(IDS_2104);
memcpy(device_name, wtemp, (wcslen(wtemp) + 1) * sizeof(WCHAR));
return;
} else if (!strcmp(internal_name, "internal"))
memcpy(temp, "Internal", 9);
else
device_get_name(device, bus, temp);
mbstowcs(device_name, temp, strlen(temp) + 1);
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c = 0;
int d = 0;
int e;
switch (message) {
case WM_INITDIALOG:
// Primary Video Card
settings_reset_content(hdlg, IDC_COMBO_VIDEO);
while (1) {
/* Skip "internal" if machine doesn't have it. */
if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) {
c++;
continue;
}
generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1);
if (!device_name[0])
break;
if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) {
if (c == 0) // "None"
settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2104));
else if (c == 1) // "Internal"
settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_VIDEO, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_gfxcard[0]))
settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO, d);
d++;
}
c++;
settings_process_messages();
}
settings_enable_window(hdlg, IDC_COMBO_VIDEO, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY));
e = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(e));
// Secondary Video Card
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_VIDEO_2);
while (1) {
/* Skip "internal" if machine doesn't have it. */
if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) {
c++;
continue;
}
generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1);
if (!device_name[0])
break;
if ((c > 1) && (video_card_get_flags(c) == video_card_get_flags(temp_gfxcard[0]))) {
c++;
continue;
}
if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) {
if (c == 0) // "None"
settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104));
else if (c == 1) // "Internal"
settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name);
settings_list_to_device[1][d] = c;
if ((c == 0) || (c == temp_gfxcard[1]))
settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d);
d++;
}
c++;
settings_process_messages();
}
settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY));
e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)];
settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e));
settings_enable_window(hdlg, IDC_CHECK_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI));
settings_set_check(hdlg, IDC_CHECK_VOODOO, temp_voodoo);
settings_enable_window(hdlg, IDC_BUTTON_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI) && temp_voodoo);
settings_enable_window(hdlg, IDC_CHECK_IBM8514, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA));
settings_set_check(hdlg, IDC_CHECK_IBM8514, temp_ibm8514);
settings_enable_window(hdlg, IDC_CHECK_XGA, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA));
settings_set_check(hdlg, IDC_CHECK_XGA, temp_xga);
settings_enable_window(hdlg, IDC_BUTTON_XGA, (machine_has_bus(temp_machine, MACHINE_BUS_ISA16) || machine_has_bus(temp_machine, MACHINE_BUS_MCA)) && temp_xga);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_COMBO_VIDEO:
temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(temp_gfxcard[0]));
// Secondary Video Card
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_VIDEO_2);
while (1) {
/* Skip "internal" if machine doesn't have it. */
if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) {
c++;
continue;
}
generate_device_name(video_card_getdevice(c), video_get_internal_name(c), 1);
if (!device_name[0])
break;
if ((c > 1) && (video_card_get_flags(c) == video_card_get_flags(temp_gfxcard[0]))) {
c++;
continue;
}
if (video_card_available(c) && device_is_valid(video_card_getdevice(c), temp_machine)) {
if (c == 0) // "None"
settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2104));
else if (c == 1) // "Internal"
settings_add_string(hdlg, IDC_COMBO_VIDEO_2, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_VIDEO_2, (LPARAM) device_name);
settings_list_to_device[1][d] = c;
if ((c == 0) || (c == temp_gfxcard[1]))
settings_set_cur_sel(hdlg, IDC_COMBO_VIDEO_2, d);
d++;
}
c++;
settings_process_messages();
}
settings_enable_window(hdlg, IDC_COMBO_VIDEO_2, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY));
e = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)];
settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(e));
break;
case IDC_COMBO_VIDEO_2:
temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)];
settings_enable_window(hdlg, IDC_CONFIGURE_VID_2, video_card_has_config(temp_gfxcard[1]));
break;
case IDC_CHECK_VOODOO:
temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO);
settings_enable_window(hdlg, IDC_BUTTON_VOODOO, temp_voodoo);
break;
case IDC_CHECK_IBM8514:
temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514);
break;
case IDC_CHECK_XGA:
temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA);
settings_enable_window(hdlg, IDC_BUTTON_XGA, temp_xga);
break;
case IDC_BUTTON_VOODOO:
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &voodoo_device);
break;
case IDC_BUTTON_XGA:
if (machine_has_bus(temp_machine, MACHINE_BUS_MCA) > 0)
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &xga_device);
else
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &xga_isa_device);
break;
case IDC_CONFIGURE_VID:
temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard[0]));
break;
case IDC_CONFIGURE_VID_2:
temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) video_card_getdevice(temp_gfxcard[1]));
break;
}
return FALSE;
case WM_SAVESETTINGS:
temp_gfxcard[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)];
temp_gfxcard[1] = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO_2)];
temp_voodoo = settings_get_check(hdlg, IDC_CHECK_VOODOO);
temp_ibm8514 = settings_get_check(hdlg, IDC_CHECK_IBM8514);
temp_xga = settings_get_check(hdlg, IDC_CHECK_XGA);
default:
return FALSE;
}
return FALSE;
}
static int
mouse_valid(int num, int m)
{
const device_t *dev;
if ((num == MOUSE_TYPE_INTERNAL) && !machine_has_flags(m, MACHINE_MOUSE))
return 0;
dev = mouse_get_device(num);
return (device_is_valid(dev, m));
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
wchar_t str[128];
char *joy_name;
int c;
int d;
switch (message) {
case WM_INITDIALOG:
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_MOUSE);
for (c = 0; c < mouse_get_ndev(); c++) {
if (mouse_valid(c, temp_machine)) {
generate_device_name(mouse_get_device(c), mouse_get_internal_name(c), 0);
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2104));
else if (c == 1)
settings_add_string(hdlg, IDC_COMBO_MOUSE, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_MOUSE, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_mouse))
settings_set_cur_sel(hdlg, IDC_COMBO_MOUSE, d);
d++;
}
}
settings_enable_window(hdlg, IDC_CONFIGURE_MOUSE, mouse_has_config(temp_mouse));
c = 0;
joy_name = joystick_get_name(c);
while (joy_name) {
mbstowcs(str, joy_name, strlen(joy_name) + 1);
settings_add_string(hdlg, IDC_COMBO_JOYSTICK, (LPARAM) str);
c++;
joy_name = joystick_get_name(c);
}
settings_enable_window(hdlg, IDC_COMBO_JOYSTICK, TRUE);
settings_set_cur_sel(hdlg, IDC_COMBO_JOYSTICK, temp_joystick);
for (c = 0; c < 4; c++)
settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_COMBO_MOUSE:
temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)];
settings_enable_window(hdlg, IDC_CONFIGURE_MOUSE, mouse_has_config(temp_mouse));
break;
case IDC_CONFIGURE_MOUSE:
temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) mouse_get_device(temp_mouse));
break;
case IDC_COMBO_JOYSTICK:
temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK);
for (c = 0; c < 4; c++)
settings_enable_window(hdlg, IDC_JOY1 + c, joystick_get_max_joysticks(temp_joystick) > c);
break;
case IDC_JOY1:
case IDC_JOY2:
case IDC_JOY3:
case IDC_JOY4:
temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK);
temp_deviceconfig |= joystickconfig_open(hdlg, LOWORD(wParam) - IDC_JOY1, temp_joystick);
break;
}
return FALSE;
case WM_SAVESETTINGS:
temp_mouse = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_MOUSE)];
temp_joystick = settings_get_cur_sel(hdlg, IDC_COMBO_JOYSTICK);
default:
return FALSE;
}
return FALSE;
}
static int
mpu401_present(void)
{
return temp_mpu401 ? 1 : 0;
}
int
mpu401_standalone_allow(void)
{
char *md;
char *mdin;
if (!machine_has_bus(temp_machine, MACHINE_BUS_ISA) && !machine_has_bus(temp_machine, MACHINE_BUS_MCA))
return 0;
md = midi_out_device_get_internal_name(temp_midi_output_device);
mdin = midi_in_device_get_internal_name(temp_midi_input_device);
if (md != NULL) {
if (!strcmp(md, "none") && !strcmp(mdin, "none"))
return 0;
}
return 1;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
uint16_t c;
uint16_t d;
LPTSTR lptsTemp;
const device_t *sound_dev[SOUND_CARD_MAX];
switch (message) {
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_SOUND1);
while (1) {
/* Skip "internal" if machine doesn't have it. */
if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_SOUND)) {
c++;
continue;
}
generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1);
if (!device_name[0])
break;
if (sound_card_available(c)) {
sound_dev[0] = sound_card_getdevice(c);
if (device_is_valid(sound_dev[0], temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SOUND1, win_get_string(IDS_2104));
else if (c == 1)
settings_add_string(hdlg, IDC_COMBO_SOUND1, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_SOUND1, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_sound_card[0]))
settings_set_cur_sel(hdlg, IDC_COMBO_SOUND1, d);
d++;
}
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_SOUND1, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SND1, sound_card_has_config(temp_sound_card[0]));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_SOUND2);
while (1) {
/* Skip "internal" */
if (c == 1) {
c++;
continue;
}
generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1);
if (!device_name[0])
break;
if (sound_card_available(c)) {
sound_dev[1] = sound_card_getdevice(c);
if (device_is_valid(sound_dev[1], temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SOUND2, win_get_string(IDS_2104));
else if (c == 1)
settings_add_string(hdlg, IDC_COMBO_SOUND2, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_SOUND2, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_sound_card[1]))
settings_set_cur_sel(hdlg, IDC_COMBO_SOUND2, d);
d++;
}
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_SOUND2, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SND2, sound_card_has_config(temp_sound_card[1]));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_SOUND3);
while (1) {
/* Skip "internal" */
if (c == 1) {
c++;
continue;
}
generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1);
if (!device_name[0])
break;
if (sound_card_available(c)) {
sound_dev[2] = sound_card_getdevice(c);
if (device_is_valid(sound_dev[2], temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SOUND3, win_get_string(IDS_2104));
else if (c == 1)
settings_add_string(hdlg, IDC_COMBO_SOUND3, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_SOUND3, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_sound_card[2]))
settings_set_cur_sel(hdlg, IDC_COMBO_SOUND3, d);
d++;
}
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_SOUND3, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SND3, sound_card_has_config(temp_sound_card[2]));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_SOUND4);
while (1) {
/* Skip "internal" */
if (c == 1) {
c++;
continue;
}
generate_device_name(sound_card_getdevice(c), sound_card_get_internal_name(c), 1);
if (!device_name[0])
break;
if (sound_card_available(c)) {
sound_dev[3] = sound_card_getdevice(c);
if (device_is_valid(sound_dev[3], temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SOUND4, win_get_string(IDS_2104));
else if (c == 1)
settings_add_string(hdlg, IDC_COMBO_SOUND4, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_SOUND4, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_sound_card[3]))
settings_set_cur_sel(hdlg, IDC_COMBO_SOUND4, d);
d++;
}
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_SOUND4, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SND4, sound_card_has_config(temp_sound_card[3]));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_MIDI_OUT);
while (1) {
generate_device_name(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0);
if (!device_name[0])
break;
if (midi_out_device_available(c)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, win_get_string(IDS_2104));
else
settings_add_string(hdlg, IDC_COMBO_MIDI_OUT, (LPARAM) device_name);
settings_list_to_midi[d] = c;
if ((c == 0) || (c == temp_midi_output_device))
settings_set_cur_sel(hdlg, IDC_COMBO_MIDI_OUT, d);
d++;
}
c++;
}
settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_OUT, midi_out_device_has_config(temp_midi_output_device));
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_MIDI_IN);
while (1) {
generate_device_name(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0);
if (!device_name[0])
break;
if (midi_in_device_available(c)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_MIDI_IN, win_get_string(IDS_2104));
else
settings_add_string(hdlg, IDC_COMBO_MIDI_IN, (LPARAM) device_name);
settings_list_to_midi_in[d] = c;
if ((c == 0) || (c == temp_midi_input_device))
settings_set_cur_sel(hdlg, IDC_COMBO_MIDI_IN, d);
d++;
}
c++;
}
settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_IN, midi_in_device_has_config(temp_midi_input_device));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
settings_set_check(hdlg, IDC_CHECK_FLOAT, temp_float);
if (temp_fm_driver == FM_DRV_YMFM)
settings_set_check(hdlg, IDC_RADIO_FM_DRV_YMFM, BST_CHECKED);
else
settings_set_check(hdlg, IDC_RADIO_FM_DRV_NUKED, BST_CHECKED);
free(lptsTemp);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_COMBO_SOUND1:
temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)];
settings_enable_window(hdlg, IDC_CONFIGURE_SND1, sound_card_has_config(temp_sound_card[0]));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
break;
case IDC_CONFIGURE_SND1:
temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[0]));
break;
case IDC_COMBO_SOUND2:
temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)];
settings_enable_window(hdlg, IDC_CONFIGURE_SND2, sound_card_has_config(temp_sound_card[1]));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
break;
case IDC_CONFIGURE_SND2:
temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[1]));
break;
case IDC_COMBO_SOUND3:
temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)];
settings_enable_window(hdlg, IDC_CONFIGURE_SND3, sound_card_has_config(temp_sound_card[2]));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
break;
case IDC_CONFIGURE_SND3:
temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[2]));
break;
case IDC_COMBO_SOUND4:
temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)];
settings_enable_window(hdlg, IDC_CONFIGURE_SND4, sound_card_has_config(temp_sound_card[3]));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
break;
case IDC_CONFIGURE_SND4:
temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card[3]));
break;
case IDC_COMBO_MIDI_OUT:
temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)];
settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_OUT, midi_out_device_has_config(temp_midi_output_device));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
break;
case IDC_CONFIGURE_MIDI_OUT:
temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) midi_out_device_getdevice(temp_midi_output_device));
break;
case IDC_COMBO_MIDI_IN:
temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)];
settings_enable_window(hdlg, IDC_CONFIGURE_MIDI_IN, midi_in_device_has_config(temp_midi_input_device));
settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401);
settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow());
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401);
break;
case IDC_CONFIGURE_MIDI_IN:
temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) midi_in_device_getdevice(temp_midi_input_device));
break;
case IDC_CHECK_MPU401:
temp_mpu401 = settings_get_check(hdlg, IDC_CHECK_MPU401);
settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_present());
break;
case IDC_CONFIGURE_MPU401:
temp_deviceconfig |= deviceconfig_open(hdlg, machine_has_bus(temp_machine, MACHINE_BUS_MCA) ? (void *) &mpu401_mca_device : (void *) &mpu401_device);
break;
}
return FALSE;
case WM_SAVESETTINGS:
temp_sound_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND1)];
temp_sound_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND2)];
temp_sound_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND3)];
temp_sound_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SOUND4)];
temp_midi_output_device = settings_list_to_midi[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_OUT)];
temp_midi_input_device = settings_list_to_midi_in[settings_get_cur_sel(hdlg, IDC_COMBO_MIDI_IN)];
temp_mpu401 = settings_get_check(hdlg, IDC_CHECK_MPU401);
temp_float = settings_get_check(hdlg, IDC_CHECK_FLOAT);
if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_NUKED))
temp_fm_driver = FM_DRV_NUKED;
if (settings_get_check(hdlg, IDC_RADIO_FM_DRV_YMFM))
temp_fm_driver = FM_DRV_YMFM;
default:
return FALSE;
}
return FALSE;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_ports_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c;
int i;
char *s;
LPTSTR lptsTemp;
switch (message) {
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
for (i = 0; i < PARALLEL_MAX; i++) {
c = 0;
while (1) {
s = lpt_device_get_name(c);
if (!s)
break;
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_LPT1 + i, win_get_string(IDS_2104));
else {
mbstowcs(lptsTemp, s, strlen(s) + 1);
settings_add_string(hdlg, IDC_COMBO_LPT1 + i, (LPARAM) lptsTemp);
}
c++;
}
settings_set_cur_sel(hdlg, IDC_COMBO_LPT1 + i, temp_lpt_devices[i]);
settings_set_check(hdlg, IDC_CHECK_PARALLEL1 + i, temp_lpt[i]);
settings_enable_window(hdlg, IDC_COMBO_LPT1 + i, temp_lpt[i]);
}
for (i = 0; i < SERIAL_MAX; i++) {
settings_set_check(hdlg, IDC_CHECK_SERIAL1 + i, temp_serial[i]);
settings_set_check(hdlg, IDC_CHECK_SERIAL_PASS1 + i, temp_serial_passthrough_enabled[i]);
}
free(lptsTemp);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_CHECK_PARALLEL1:
case IDC_CHECK_PARALLEL2:
case IDC_CHECK_PARALLEL3:
case IDC_CHECK_PARALLEL4:
i = LOWORD(wParam) - IDC_CHECK_PARALLEL1;
settings_enable_window(hdlg, IDC_COMBO_LPT1 + i,
settings_get_check(hdlg, IDC_CHECK_PARALLEL1 + i) == BST_CHECKED);
break;
}
break;
case WM_SAVESETTINGS:
for (i = 0; i < PARALLEL_MAX; i++) {
temp_lpt_devices[i] = settings_get_cur_sel(hdlg, IDC_COMBO_LPT1 + i);
temp_lpt[i] = settings_get_check(hdlg, IDC_CHECK_PARALLEL1 + i);
}
for (i = 0; i < SERIAL_MAX; i++) {
temp_serial[i] = settings_get_check(hdlg, IDC_CHECK_SERIAL1 + i);
temp_serial_passthrough_enabled[i] = settings_get_check(hdlg, IDC_CHECK_SERIAL_PASS1 + i);
}
default:
return FALSE;
}
return FALSE;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c;
int d;
int e;
int is_at;
LPTSTR lptsTemp;
char *stransi;
const device_t *scsi_dev;
const device_t *fdc_dev;
const device_t *hdc_dev;
switch (message) {
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
stransi = (char *) malloc(512);
/*HD controller config*/
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_HDC);
while (1) {
/* Skip "internal" if machine doesn't have it. */
if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_HDC)) {
c++;
continue;
}
generate_device_name(hdc_get_device(c), hdc_get_internal_name(c), 1);
if (!device_name[0])
break;
if (hdc_available(c)) {
hdc_dev = hdc_get_device(c);
if (device_is_valid(hdc_dev, temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2104));
else if (c == 1)
settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_HDC, (LPARAM) device_name);
settings_list_to_hdc[d] = c;
if ((c == 0) || (c == temp_hdc))
settings_set_cur_sel(hdlg, IDC_COMBO_HDC, d);
d++;
}
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_HDC, d);
settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc));
/*FD controller config*/
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_FDC);
while (1) {
generate_device_name(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1);
if (!device_name[0])
break;
if (fdc_card_available(c)) {
fdc_dev = fdc_card_getdevice(c);
if (device_is_valid(fdc_dev, temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_FDC, win_get_string(IDS_2119));
else
settings_add_string(hdlg, IDC_COMBO_FDC, (LPARAM) device_name);
settings_list_to_fdc[d] = c;
if ((c == 0) || (c == temp_fdc_card))
settings_set_cur_sel(hdlg, IDC_COMBO_FDC, d);
d++;
}
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_FDC, d);
settings_enable_window(hdlg, IDC_CONFIGURE_FDC, fdc_card_has_config(temp_fdc_card));
/*SCSI config*/
c = d = 0;
for (e = 0; e < SCSI_BUS_MAX; e++)
settings_reset_content(hdlg, IDC_COMBO_SCSI_1 + e);
while (1) {
generate_device_name(scsi_card_getdevice(c), scsi_card_get_internal_name(c), 1);
if (!device_name[0])
break;
if (scsi_card_available(c)) {
scsi_dev = scsi_card_getdevice(c);
if (device_is_valid(scsi_dev, temp_machine)) {
for (e = 0; e < SCSI_BUS_MAX; e++) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2104));
else
settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, (LPARAM) device_name);
if ((c == 0) || (c == temp_scsi_card[e]))
settings_set_cur_sel(hdlg, IDC_COMBO_SCSI_1 + e, d);
}
settings_list_to_device[0][d] = c;
d++;
}
}
c++;
}
for (c = 0; c < SCSI_BUS_MAX; c++) {
settings_enable_window(hdlg, IDC_COMBO_SCSI_1 + c, d);
settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c]));
}
is_at = IS_AT(temp_machine);
settings_enable_window(hdlg, IDC_CHECK_IDE_TER, is_at);
settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, is_at && temp_ide_ter);
settings_enable_window(hdlg, IDC_CHECK_IDE_QUA, is_at);
settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, is_at && temp_ide_qua);
settings_enable_window(hdlg, IDC_CHECK_CASSETTE, machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE));
settings_set_check(hdlg, IDC_CHECK_IDE_TER, temp_ide_ter);
settings_set_check(hdlg, IDC_CHECK_IDE_QUA, temp_ide_qua);
settings_set_check(hdlg, IDC_CHECK_CASSETTE, (temp_cassette && machine_has_bus(temp_machine, MACHINE_BUS_CASSETTE)));
free(stransi);
free(lptsTemp);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_CONFIGURE_FDC:
temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) fdc_card_getdevice(temp_fdc_card));
break;
case IDC_COMBO_FDC:
temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)];
settings_enable_window(hdlg, IDC_CONFIGURE_FDC, fdc_card_has_config(temp_fdc_card));
break;
case IDC_CONFIGURE_HDC:
temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) hdc_get_device(temp_hdc));
break;
case IDC_COMBO_HDC:
temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)];
settings_enable_window(hdlg, IDC_CONFIGURE_HDC, hdc_has_config(temp_hdc));
break;
case IDC_CONFIGURE_SCSI_1 ... IDC_CONFIGURE_SCSI_4:
c = LOWORD(wParam) - IDC_CONFIGURE_SCSI_1;
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *) scsi_card_getdevice(temp_scsi_card[c]), c + 1);
break;
case IDC_COMBO_SCSI_1 ... IDC_COMBO_SCSI_4:
c = LOWORD(wParam) - IDC_COMBO_SCSI_1;
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
settings_enable_window(hdlg, IDC_CONFIGURE_SCSI_1 + c, scsi_card_has_config(temp_scsi_card[c]));
break;
case IDC_CHECK_IDE_TER:
temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER);
settings_enable_window(hdlg, IDC_BUTTON_IDE_TER, temp_ide_ter);
break;
case IDC_BUTTON_IDE_TER:
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &ide_ter_device);
break;
case IDC_CHECK_IDE_QUA:
temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA);
settings_enable_window(hdlg, IDC_BUTTON_IDE_QUA, temp_ide_qua);
break;
case IDC_BUTTON_IDE_QUA:
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) &ide_qua_device);
break;
}
return FALSE;
case WM_SAVESETTINGS:
temp_hdc = settings_list_to_hdc[settings_get_cur_sel(hdlg, IDC_COMBO_HDC)];
temp_fdc_card = settings_list_to_fdc[settings_get_cur_sel(hdlg, IDC_COMBO_FDC)];
for (c = 0; c < SCSI_BUS_MAX; c++)
temp_scsi_card[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_SCSI_1 + c)];
temp_ide_ter = settings_get_check(hdlg, IDC_CHECK_IDE_TER);
temp_ide_qua = settings_get_check(hdlg, IDC_CHECK_IDE_QUA);
temp_cassette = settings_get_check(hdlg, IDC_CHECK_CASSETTE);
default:
return FALSE;
}
return FALSE;
}
static void
network_recalc_combos(HWND hdlg)
{
ignore_change = 1;
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP);
settings_enable_window(hdlg, IDC_COMBO_NET1 + i,
(temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0)));
settings_enable_window(hdlg, IDC_CONFIGURE_NET1 + i, network_card_has_config(temp_net_card[i]) && ((temp_net_type[i] == NET_TYPE_SLIRP) || ((temp_net_type[i] == NET_TYPE_PCAP) && (network_dev_to_id(temp_pcap_dev[i]) > 0))));
}
ignore_change = 0;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c;
int d;
LPTSTR lptsTemp;
switch (message) {
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"Null Driver");
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"SLiRP");
settings_add_string(hdlg, IDC_COMBO_NET1_TYPE + i, (LPARAM) L"PCap");
settings_set_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i, temp_net_type[i]);
settings_enable_window(hdlg, IDC_COMBO_PCAP1 + i, temp_net_type[i] == NET_TYPE_PCAP);
for (c = 0; c < network_ndev; c++) {
mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1);
settings_add_string(hdlg, IDC_COMBO_PCAP1 + i, (LPARAM) lptsTemp);
}
settings_set_cur_sel(hdlg, IDC_COMBO_PCAP1 + i, network_dev_to_id(temp_pcap_dev[i]));
/* NIC config */
c = d = 0;
settings_reset_content(hdlg, IDC_COMBO_NET1 + i);
while (1) {
generate_device_name(network_card_getdevice(c), network_card_get_internal_name(c), 1);
if (device_name[0] == L'\0')
break;
if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) {
if (c == 0)
settings_add_string(hdlg, IDC_COMBO_NET1 + i, win_get_string(IDS_2104));
else
settings_add_string(hdlg, IDC_COMBO_NET1 + i, (LPARAM) device_name);
settings_list_to_device[0][d] = c;
if ((c == 0) || (c == temp_net_card[i]))
settings_set_cur_sel(hdlg, IDC_COMBO_NET1 + i, d);
d++;
}
c++;
}
settings_enable_window(hdlg, IDC_COMBO_NET1 + i, d);
network_recalc_combos(hdlg);
}
free(lptsTemp);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_COMBO_NET1_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[0] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET2_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[1] = settings_get_cur_sel(hdlg, IDC_COMBO_NET2_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET3_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[2] = settings_get_cur_sel(hdlg, IDC_COMBO_NET3_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET4_TYPE:
if (ignore_change)
return FALSE;
temp_net_type[3] = settings_get_cur_sel(hdlg, IDC_COMBO_NET4_TYPE);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP1:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[0], '\0', sizeof(temp_pcap_dev[0]));
strcpy(temp_pcap_dev[0], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP2:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[1], '\0', sizeof(temp_pcap_dev[1]));
strcpy(temp_pcap_dev[1], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP2)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP3:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[2], '\0', sizeof(temp_pcap_dev[2]));
strcpy(temp_pcap_dev[2], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP3)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_PCAP4:
if (ignore_change)
return FALSE;
memset(temp_pcap_dev[3], '\0', sizeof(temp_pcap_dev[3]));
strcpy(temp_pcap_dev[3], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP4)].device);
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET1:
if (ignore_change)
return FALSE;
temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)];
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET2:
if (ignore_change)
return FALSE;
temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)];
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET3:
if (ignore_change)
return FALSE;
temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)];
network_recalc_combos(hdlg);
break;
case IDC_COMBO_NET4:
if (ignore_change)
return FALSE;
temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)];
network_recalc_combos(hdlg);
break;
case IDC_CONFIGURE_NET1:
if (ignore_change)
return FALSE;
temp_net_card[0] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[0]));
break;
case IDC_CONFIGURE_NET2:
if (ignore_change)
return FALSE;
temp_net_card[1] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET2)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[1]));
break;
case IDC_CONFIGURE_NET3:
if (ignore_change)
return FALSE;
temp_net_card[2] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET3)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[2]));
break;
case IDC_CONFIGURE_NET4:
if (ignore_change)
return FALSE;
temp_net_card[3] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET4)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) network_card_getdevice(temp_net_card[3]));
break;
}
return FALSE;
case WM_SAVESETTINGS:
for (uint8_t i = 0; i < NET_CARD_MAX; i++) {
temp_net_type[i] = settings_get_cur_sel(hdlg, IDC_COMBO_NET1_TYPE + i);
memset(temp_pcap_dev[i], '\0', sizeof(temp_pcap_dev[i]));
strcpy(temp_pcap_dev[i], network_devs[settings_get_cur_sel(hdlg, IDC_COMBO_PCAP1 + i)].device);
temp_net_card[i] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_NET1 + i)];
}
default:
return FALSE;
}
return FALSE;
}
static void
normalize_hd_list(void)
{
hard_disk_t ihdd[HDD_NUM];
int j = 0;
memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t));
for (uint8_t i = 0; i < HDD_NUM; i++) {
if (temp_hdd[i].bus != HDD_BUS_DISABLED) {
memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t));
j++;
}
}
memcpy(temp_hdd, ihdd, HDD_NUM * sizeof(hard_disk_t));
}
static int
get_selected_hard_disk(HWND hdlg)
{
int hard_disk = -1;
int j = 0;
HWND h;
if (hd_listview_items == 0)
return 0;
for (int i = 0; i < hd_listview_items; i++) {
h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
j = ListView_GetItemState(h, i, LVIS_SELECTED);
if (j)
hard_disk = i;
}
return hard_disk;
}
static void
add_locations(HWND hdlg)
{
LPTSTR lptsTemp;
int i = 0;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
for (i = 0; i < 6; i++)
settings_add_string(hdlg, IDC_COMBO_HD_BUS, win_get_string(IDS_4352 + i));
for (i = 0; i < 2; i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL, (LPARAM) lptsTemp);
}
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_HD_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_HD_CHANNEL_IDE, (LPARAM) lptsTemp);
}
free(lptsTemp);
}
static uint8_t
next_free_binary_channel(uint64_t *tracking)
{
for (int64_t i = 0; i < 2; i++) {
if (!(*tracking & (0xffLL << (i << 3LL))))
return i;
}
return 2;
}
static uint8_t
next_free_ide_channel(void)
{
for (int64_t i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
if (!(ide_tracking & (0xffLL << (i << 3LL))))
return i;
}
return 7;
}
static void
next_free_scsi_id(uint8_t *id)
{
for (int64_t i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
if (!(scsi_tracking[i >> 3] & (0xffLL << ((i & 0x07) << 3LL)))) {
*id = i;
return;
}
}
*id = 6;
}
static void
recalc_location_controls(HWND hdlg, int is_add_dlg, int assign_id)
{
int bus = 0;
for (uint16_t i = IDT_CHANNEL; i <= IDT_ID; i++)
settings_show_window(hdlg, i, FALSE);
settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, FALSE);
settings_show_window(hdlg, IDC_COMBO_HD_ID, FALSE);
settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL_IDE, FALSE);
if ((hd_listview_items > 0) || is_add_dlg) {
bus = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1;
switch (bus) {
case HDD_BUS_MFM: /* MFM */
settings_show_window(hdlg, IDT_CHANNEL, TRUE);
settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE);
if (assign_id)
temp_hdd[lv1_current_sel].mfm_channel = next_free_binary_channel(&mfm_tracking);
settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.mfm_channel : temp_hdd[lv1_current_sel].mfm_channel);
break;
case HDD_BUS_XTA: /* XTA */
settings_show_window(hdlg, IDT_CHANNEL, TRUE);
settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE);
if (assign_id)
temp_hdd[lv1_current_sel].xta_channel = next_free_binary_channel(&xta_tracking);
settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.xta_channel : temp_hdd[lv1_current_sel].xta_channel);
break;
case HDD_BUS_ESDI: /* ESDI */
settings_show_window(hdlg, IDT_CHANNEL, TRUE);
settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL, TRUE);
if (assign_id)
temp_hdd[lv1_current_sel].esdi_channel = next_free_binary_channel(&esdi_tracking);
settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, is_add_dlg ? new_hdd.esdi_channel : temp_hdd[lv1_current_sel].esdi_channel);
break;
case HDD_BUS_IDE: /* IDE */
case HDD_BUS_ATAPI: /* ATAPI */
settings_show_window(hdlg, IDT_CHANNEL, TRUE);
settings_show_window(hdlg, IDC_COMBO_HD_CHANNEL_IDE, TRUE);
if (assign_id)
temp_hdd[lv1_current_sel].ide_channel = next_free_ide_channel();
settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE, is_add_dlg ? new_hdd.ide_channel : temp_hdd[lv1_current_sel].ide_channel);
break;
case HDD_BUS_SCSI: /* SCSI */
settings_show_window(hdlg, IDT_ID, TRUE);
settings_show_window(hdlg, IDT_LUN, TRUE);
settings_show_window(hdlg, IDC_COMBO_HD_ID, TRUE);
if (assign_id)
next_free_scsi_id((uint8_t *) (is_add_dlg ? &(new_hdd.scsi_id) : &(temp_hdd[lv1_current_sel].scsi_id)));
settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, is_add_dlg ? new_hdd.scsi_id : temp_hdd[lv1_current_sel].scsi_id);
}
}
settings_show_window(hdlg, IDT_BUS, (hd_listview_items != 0) || is_add_dlg);
settings_show_window(hdlg, IDC_COMBO_HD_BUS, (hd_listview_items != 0) || is_add_dlg);
}
static int
bus_full(uint64_t *tracking, int count)
{
int full = 0;
switch (count) {
case 2:
default:
full = (*tracking & 0xFF00LL);
full = full && (*tracking & 0x00FFLL);
break;
case 8:
full = (*tracking & 0xFF00000000000000LL);
full = full && (*tracking & 0x00FF000000000000LL);
full = full && (*tracking & 0x0000FF0000000000LL);
full = full && (*tracking & 0x000000FF00000000LL);
full = full && (*tracking & 0x00000000FF000000LL);
full = full && (*tracking & 0x0000000000FF0000LL);
full = full && (*tracking & 0x000000000000FF00LL);
full = full && (*tracking & 0x00000000000000FFLL);
break;
}
return full;
}
static void
recalc_next_free_id(HWND hdlg)
{
int i;
int enable_add = 0;
int c_mfm = 0;
int c_esdi = 0;
int c_xta = 0;
int c_ide = 0;
int c_atapi = 0;
int c_scsi = 0;
next_free_id = -1;
for (i = 0; i < HDD_NUM; i++) {
if (temp_hdd[i].bus == HDD_BUS_MFM)
c_mfm++;
else if (temp_hdd[i].bus == HDD_BUS_ESDI)
c_esdi++;
else if (temp_hdd[i].bus == HDD_BUS_XTA)
c_xta++;
else if (temp_hdd[i].bus == HDD_BUS_IDE)
c_ide++;
else if (temp_hdd[i].bus == HDD_BUS_ATAPI)
c_atapi++;
else if (temp_hdd[i].bus == HDD_BUS_SCSI)
c_scsi++;
}
for (i = 0; i < HDD_NUM; i++) {
if (temp_hdd[i].bus == HDD_BUS_DISABLED) {
next_free_id = i;
break;
}
}
enable_add = enable_add || (next_free_id >= 0);
enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_esdi < ESDI_NUM) || (c_xta < XTA_NUM) || (c_ide < IDE_NUM) || (c_ide < ATAPI_NUM) || (c_scsi < SCSI_NUM));
enable_add = enable_add && (!bus_full(&mfm_tracking, 2) || !bus_full(&esdi_tracking, 2) || !bus_full(&xta_tracking, 2) || !bus_full(&ide_tracking, IDE_CHAN_MAX * IDE_BUS_MAX) ||
!bus_full(&(scsi_tracking[0]), 8) || !bus_full(&(scsi_tracking[1]), 8) || !bus_full(&(scsi_tracking[2]), 8) || !bus_full(&(scsi_tracking[3]), 8) ||
!bus_full(&(scsi_tracking[4]), 8) || !bus_full(&(scsi_tracking[5]), 8) || !bus_full(&(scsi_tracking[6]), 8) || !bus_full(&(scsi_tracking[7]), 8));
settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD_NEW, enable_add);
settings_enable_window(hdlg, IDC_BUTTON_HDD_ADD, enable_add);
settings_enable_window(hdlg, IDC_BUTTON_HDD_REMOVE,
(c_mfm != 0) || (c_esdi != 0) || (c_xta != 0) || (c_ide != 0) || (c_atapi != 0) || (c_scsi != 0));
}
static void
win_settings_hard_disks_update_item(HWND hdlg, int i, int column)
{
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
LVITEM lvI;
WCHAR szText[256];
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
lvI.iSubItem = column;
lvI.iItem = i;
if (column == 0) { /* Bus */
switch (temp_hdd[i].bus) {
case HDD_BUS_MFM:
wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1);
break;
case HDD_BUS_XTA:
wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1);
break;
case HDD_BUS_ESDI:
wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1);
break;
case HDD_BUS_IDE:
wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
break;
case HDD_BUS_ATAPI:
wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
break;
case HDD_BUS_SCSI:
wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id & 15);
break;
}
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 1) { /* File */
if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path)))
mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText));
else
mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText));
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 2) { /* Cylinders */
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks);
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 3) { /* Heads */
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc);
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 4) { /* Sectors */
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt);
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 5) { /* Size (MB) */
wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11);
lvI.pszText = szText;
lvI.iImage = 0;
} else if (column == 6) { /* Speed (RPM) */
mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText));
lvI.pszText = szText;
lvI.iImage = 0;
}
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
}
static BOOL
win_settings_hard_disks_recalc_list(HWND hdlg)
{
LVITEM lvI;
int j = 0;
WCHAR szText[256];
WCHAR usr_path_w[1024];
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
mbstoc16s(usr_path_w, usr_path, sizeof_w(usr_path_w));
hd_listview_items = 0;
lv1_current_sel = -1;
ListView_DeleteAllItems(hwndList);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
for (uint8_t i = 0; i < HDD_NUM; i++) {
if (temp_hdd[i].bus > 0) {
hdc_id_to_listview_index[i] = j;
lvI.iSubItem = 0;
/* Bus */
switch (temp_hdd[i].bus) {
case HDD_BUS_MFM:
wsprintf(szText, plat_get_string(IDS_4608), temp_hdd[i].mfm_channel >> 1, temp_hdd[i].mfm_channel & 1);
break;
case HDD_BUS_XTA:
wsprintf(szText, plat_get_string(IDS_4609), temp_hdd[i].xta_channel >> 1, temp_hdd[i].xta_channel & 1);
break;
case HDD_BUS_ESDI:
wsprintf(szText, plat_get_string(IDS_4610), temp_hdd[i].esdi_channel >> 1, temp_hdd[i].esdi_channel & 1);
break;
case HDD_BUS_IDE:
wsprintf(szText, plat_get_string(IDS_4611), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
break;
case HDD_BUS_ATAPI:
wsprintf(szText, plat_get_string(IDS_4612), temp_hdd[i].ide_channel >> 1, temp_hdd[i].ide_channel & 1);
break;
case HDD_BUS_SCSI:
wsprintf(szText, plat_get_string(IDS_4613), temp_hdd[i].scsi_id >> 4, temp_hdd[i].scsi_id & 15);
break;
}
lvI.pszText = szText;
lvI.iItem = j;
lvI.iImage = 0;
if (ListView_InsertItem(hwndList, &lvI) == -1)
return FALSE;
/* File */
lvI.iSubItem = 1;
if (!strnicmp(temp_hdd[i].fn, usr_path, strlen(usr_path)))
mbstoc16s(szText, temp_hdd[i].fn + strlen(usr_path), sizeof_w(szText));
else
mbstoc16s(szText, temp_hdd[i].fn, sizeof_w(szText));
lvI.pszText = szText;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/* Cylinders */
lvI.iSubItem = 2;
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].tracks);
lvI.pszText = szText;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/* Heads */
lvI.iSubItem = 3;
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].hpc);
lvI.pszText = szText;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/* Sectors */
lvI.iSubItem = 4;
wsprintf(szText, plat_get_string(IDS_4098), temp_hdd[i].spt);
lvI.pszText = szText;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/* Size (MB) */
lvI.iSubItem = 5;
wsprintf(szText, plat_get_string(IDS_4098), (temp_hdd[i].tracks * temp_hdd[i].hpc * temp_hdd[i].spt) >> 11);
lvI.pszText = szText;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/* Speed (RPM) */
lvI.iSubItem = 6;
mbstoc16s(szText, hdd_preset_getname(temp_hdd[i].speed_preset), sizeof_w(szText));
lvI.pszText = szText;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
j++;
} else
hdc_id_to_listview_index[i] = -1;
}
hd_listview_items = j;
return TRUE;
}
#define C_COLUMNS_HARD_DISKS_BUS 104
#define C_COLUMNS_HARD_DISKS_FILE 254
#define C_COLUMNS_HARD_DISKS_CYLS 50
#define C_COLUMNS_HARD_DISKS_HEADS 26
#define C_COLUMNS_HARD_DISKS_SECT 32
#define C_COLUMNS_HARD_DISKS_SIZE 50
#define C_COLUMNS_HARD_DISKS_SPEED 100
static void
win_settings_hard_disks_resize_columns(HWND hdlg)
{
/* Bus, File, Cylinders, Heads, Sectors, Size */
int width[C_COLUMNS_HARD_DISKS] = {
C_COLUMNS_HARD_DISKS_BUS,
C_COLUMNS_HARD_DISKS_FILE,
C_COLUMNS_HARD_DISKS_CYLS,
C_COLUMNS_HARD_DISKS_HEADS,
C_COLUMNS_HARD_DISKS_SECT,
C_COLUMNS_HARD_DISKS_SIZE,
C_COLUMNS_HARD_DISKS_SPEED
};
int total = 0;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
RECT r;
GetWindowRect(hwndList, &r);
for (int iCol = 0; iCol < (C_COLUMNS_HARD_DISKS - 1); iCol++) {
width[iCol] = MulDiv(width[iCol], dpi, 96);
total += width[iCol];
ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96));
}
width[C_COLUMNS_HARD_DISKS - 1] = (r.right - r.left) - 4 - total;
ListView_SetColumnWidth(hwndList, C_COLUMNS_HARD_DISKS - 1, width[C_COLUMNS_HARD_DISKS - 1]);
}
static BOOL
win_settings_hard_disks_init_columns(HWND hdlg)
{
LVCOLUMN lvc;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
for (int iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) {
lvc.iSubItem = iCol;
lvc.pszText = plat_get_string(IDS_BUS + iCol);
switch (iCol) {
case 0: /* Bus */
lvc.cx = C_COLUMNS_HARD_DISKS_BUS;
lvc.fmt = LVCFMT_LEFT;
break;
case 1: /* File */
lvc.cx = C_COLUMNS_HARD_DISKS_FILE;
lvc.fmt = LVCFMT_LEFT;
break;
case 2: /* Cylinders */
lvc.cx = C_COLUMNS_HARD_DISKS_CYLS;
lvc.fmt = LVCFMT_RIGHT;
break;
case 3: /* Heads */
lvc.cx = C_COLUMNS_HARD_DISKS_HEADS;
lvc.fmt = LVCFMT_RIGHT;
break;
case 4: /* Sectors */
lvc.cx = C_COLUMNS_HARD_DISKS_SECT;
lvc.fmt = LVCFMT_RIGHT;
break;
case 5: /* Size (MB) */
lvc.cx = C_COLUMNS_HARD_DISKS_SIZE;
lvc.fmt = LVCFMT_RIGHT;
break;
case 6: /* Speed (RPM) */
lvc.cx = C_COLUMNS_HARD_DISKS_SPEED;
lvc.fmt = LVCFMT_RIGHT;
break;
}
if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1)
return FALSE;
}
win_settings_hard_disks_resize_columns(hdlg);
return TRUE;
}
static void
get_edit_box_contents(HWND hdlg, int id, uint32_t *val)
{
HWND h;
WCHAR szText[256];
char stransi[256];
h = GetDlgItem(hdlg, id);
SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText);
wcstombs(stransi, szText, 256);
sscanf(stransi, "%u", val);
}
static void
set_edit_box_contents(HWND hdlg, int id, uint32_t val)
{
HWND h;
WCHAR szText[256];
h = GetDlgItem(hdlg, id);
wsprintf(szText, plat_get_string(IDS_2107), val);
SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText);
}
static void
set_edit_box_text_contents(HWND hdlg, int id, WCHAR *text)
{
HWND h = GetDlgItem(hdlg, id);
SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(text), (LPARAM) text);
}
static void
get_edit_box_text_contents(HWND hdlg, int id, WCHAR *text_buffer, int buffer_size)
{
HWND h = GetDlgItem(hdlg, id);
SendMessage(h, WM_GETTEXT, (WPARAM) buffer_size, (LPARAM) text_buffer);
}
static int
hdconf_initialize_hdt_combo(HWND hdlg)
{
uint64_t temp_size = 0;
uint32_t size_mb = 0;
WCHAR szText[256];
selection = 127;
for (uint8_t i = 0; i < 127; i++) {
temp_size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2];
size_mb = (uint32_t) (temp_size >> 11LL);
wsprintf(szText, plat_get_string(IDS_2108), size_mb, hdd_table[i][0], hdd_table[i][1], hdd_table[i][2]);
settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) szText);
if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2]))
selection = i;
}
settings_add_string(hdlg, IDC_COMBO_HD_TYPE, win_get_string(IDS_4100));
settings_add_string(hdlg, IDC_COMBO_HD_TYPE, win_get_string(IDS_4101));
settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection);
return selection;
}
static void
recalc_selection(HWND hdlg)
{
selection = 127;
for (uint8_t i = 0; i < 127; i++) {
if ((tracks == (int) hdd_table[i][0]) && (hpc == (int) hdd_table[i][1]) && (spt == (int) hdd_table[i][2]))
selection = i;
}
if ((selection == 127) && (hpc == 16) && (spt == 63))
selection = 128;
settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, selection);
}
HWND vhd_progress_hdlg;
static void
vhd_progress_callback(uint32_t current_sector, uint32_t total_sectors)
{
MSG msg;
HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE);
SendMessage(h, PBM_SETPOS, (WPARAM) current_sector, (LPARAM) 0);
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
/* If the disk geometry requested in the 86Box GUI is not compatible with the internal VHD geometry,
* we adjust it to the next-largest size that is compatible. On average, this will be a difference
* of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more
* than a tenth of a percent change in size.
*/
static void
adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry)
{
if (_86box_geometry->cyl <= 65535) {
vhd_geometry->cyl = _86box_geometry->cyl;
vhd_geometry->heads = _86box_geometry->heads;
vhd_geometry->spt = _86box_geometry->spt;
return;
}
int desired_sectors = _86box_geometry->cyl * _86box_geometry->heads * _86box_geometry->spt;
if (desired_sectors > 267321600)
desired_sectors = 267321600;
int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */
if (remainder > 0)
desired_sectors += (85680 - remainder);
_86box_geometry->cyl = desired_sectors / (16 * 63);
_86box_geometry->heads = 16;
_86box_geometry->spt = 63;
vhd_geometry->cyl = desired_sectors / (16 * 255);
vhd_geometry->heads = 16;
vhd_geometry->spt = 255;
}
static void
adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry)
{
if (vhd_geometry->spt <= 63)
return;
int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt;
if (desired_sectors > 267321600)
desired_sectors = 267321600;
int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */
if (remainder > 0)
desired_sectors -= remainder;
vhd_geometry->cyl = desired_sectors / (16 * 63);
vhd_geometry->heads = 16;
vhd_geometry->spt = 63;
}
static MVHDGeom
create_drive_vhd_fixed(char *filename, int cyl, int heads, int spt)
{
MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt };
MVHDGeom vhd_geometry;
adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry);
HWND h = GetDlgItem(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE);
settings_show_window(vhd_progress_hdlg, IDT_FILE_NAME, FALSE);
settings_show_window(vhd_progress_hdlg, IDC_EDIT_HD_FILE_NAME, FALSE);
settings_show_window(vhd_progress_hdlg, IDC_CFILE, FALSE);
settings_show_window(vhd_progress_hdlg, IDC_PBAR_IMG_CREATE, TRUE);
settings_enable_window(vhd_progress_hdlg, IDT_PROGRESS, TRUE);
SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) vhd_geometry.cyl * vhd_geometry.heads * vhd_geometry.spt);
SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
int vhd_error = 0;
MVHDMeta *vhd = mvhd_create_fixed(filename, vhd_geometry, &vhd_error, vhd_progress_callback);
if (vhd == NULL) {
_86box_geometry.cyl = 0;
_86box_geometry.heads = 0;
_86box_geometry.spt = 0;
} else {
mvhd_close(vhd);
}
return _86box_geometry;
}
static MVHDGeom
create_drive_vhd_dynamic(char *filename, int cyl, int heads, int spt, int blocksize)
{
MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt };
MVHDGeom vhd_geometry;
adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry);
int vhd_error = 0;
MVHDCreationOptions options;
options.block_size_in_sectors = blocksize;
options.path = filename;
options.size_in_bytes = 0;
options.geometry = vhd_geometry;
options.type = MVHD_TYPE_DYNAMIC;
MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error);
if (vhd == NULL) {
_86box_geometry.cyl = 0;
_86box_geometry.heads = 0;
_86box_geometry.spt = 0;
} else {
mvhd_close(vhd);
}
return _86box_geometry;
}
static MVHDGeom
create_drive_vhd_diff(char *filename, char *parent_filename, int blocksize)
{
int vhd_error = 0;
MVHDCreationOptions options;
options.block_size_in_sectors = blocksize;
options.path = filename;
options.parent_path = parent_filename;
options.type = MVHD_TYPE_DIFF;
MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error);
MVHDGeom vhd_geometry;
if (vhd == NULL) {
vhd_geometry.cyl = 0;
vhd_geometry.heads = 0;
vhd_geometry.spt = 0;
} else {
vhd_geometry = mvhd_get_geometry(vhd);
if (vhd_geometry.spt > 63) {
vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63);
vhd_geometry.heads = 16;
vhd_geometry.spt = 63;
}
mvhd_close(vhd);
}
return vhd_geometry;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND h;
FILE *f;
uint32_t temp;
uint32_t i = 0;
uint32_t sector_size = 512;
uint32_t zero = 0;
uint32_t base = 0x1000;
uint64_t signature = 0xD778A82044445459LL;
uint64_t r = 0;
char *big_buf;
char hd_file_name_multibyte[1200];
int b = 0;
int vhd_error = 0;
uint8_t channel = 0;
uint8_t id = 0;
wchar_t *twcs;
int img_format;
int block_size;
WCHAR text_buf[256];
RECT rect;
POINT point;
int dlg_height_adjust;
switch (message) {
case WM_INITDIALOG:
memset(hd_file_name, 0, sizeof(hd_file_name));
hdd_ptr = &(temp_hdd[next_free_id]);
SetWindowText(hdlg, plat_get_string((existing & 1) ? IDS_4103 : IDS_4102));
no_update = 1;
spt = (existing & 1) ? 0 : 17;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt);
hpc = (existing & 1) ? 0 : 15;
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc);
tracks = (existing & 1) ? 0 : 1023;
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks);
size = (tracks * hpc * spt) << 9;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20LL));
hdconf_initialize_hdt_combo(hdlg);
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4122));
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4123));
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4124));
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4125));
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4126));
settings_add_string(hdlg, IDC_COMBO_HD_IMG_FORMAT, win_get_string(IDS_4127));
settings_set_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT, 0);
settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, win_get_string(IDS_4128));
settings_add_string(hdlg, IDC_COMBO_HD_BLOCK_SIZE, win_get_string(IDS_4129));
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE, 0);
settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE);
settings_show_window(hdlg, IDT_BLOCK_SIZE, FALSE);
if (existing & 1) {
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE);
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE);
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE);
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE);
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE);
settings_show_window(hdlg, IDC_COMBO_HD_IMG_FORMAT, FALSE);
settings_show_window(hdlg, IDT_IMG_FORMAT, FALSE);
/* adjust window size */
GetWindowRect(hdlg, &rect);
OffsetRect(&rect, -rect.left, -rect.top);
dlg_height_adjust = rect.bottom / 5;
SetWindowPos(hdlg, NULL, 0, 0, rect.right, rect.bottom - dlg_height_adjust, SWP_NOMOVE | SWP_NOREPOSITION | SWP_NOZORDER);
h = GetDlgItem(hdlg, IDOK);
GetWindowRect(h, &rect);
point.x = rect.left;
point.y = rect.top;
ScreenToClient(hdlg, &point);
SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER);
h = GetDlgItem(hdlg, IDCANCEL);
GetWindowRect(h, &rect);
point.x = rect.left;
point.y = rect.top;
ScreenToClient(hdlg, &point);
SetWindowPos(h, NULL, point.x, point.y - dlg_height_adjust, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_NOZORDER);
chs_enabled = 0;
} else
chs_enabled = 1;
add_locations(hdlg);
hdd_ptr->bus = HDD_BUS_IDE;
max_spt = 255;
max_hpc = 255;
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, hdd_ptr->bus - 1);
max_tracks = 266305;
recalc_location_controls(hdlg, 1, 0);
channel = next_free_ide_channel();
next_free_scsi_id(&id);
settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL, 0);
settings_set_cur_sel(hdlg, IDC_COMBO_HD_ID, id);
settings_set_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE, channel);
new_hdd.mfm_channel = next_free_binary_channel(&mfm_tracking);
new_hdd.esdi_channel = next_free_binary_channel(&esdi_tracking);
new_hdd.xta_channel = next_free_binary_channel(&xta_tracking);
new_hdd.ide_channel = channel;
new_hdd.scsi_id = id;
settings_enable_window(hdlg, IDC_EDIT_HD_FILE_NAME, FALSE);
settings_show_window(hdlg, IDT_PROGRESS, FALSE);
settings_show_window(hdlg, IDC_PBAR_IMG_CREATE, FALSE);
no_update = 0;
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
hdd_ptr->bus = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1;
/* Make sure no file name is allowed with removable SCSI hard disks. */
if (wcslen(hd_file_name) == 0) {
hdd_ptr->bus = HDD_BUS_DISABLED;
settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2131, (wchar_t *) IDS_4112);
return TRUE;
}
get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdd_ptr->spt));
get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdd_ptr->hpc));
get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdd_ptr->tracks));
spt = hdd_ptr->spt;
hpc = hdd_ptr->hpc;
tracks = hdd_ptr->tracks;
switch (hdd_ptr->bus) {
case HDD_BUS_MFM:
hdd_ptr->mfm_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL);
break;
case HDD_BUS_ESDI:
hdd_ptr->esdi_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL);
break;
case HDD_BUS_XTA:
hdd_ptr->xta_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL);
break;
case HDD_BUS_IDE:
case HDD_BUS_ATAPI:
hdd_ptr->ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE);
break;
case HDD_BUS_SCSI:
hdd_ptr->scsi_id = settings_get_cur_sel(hdlg, IDC_COMBO_HD_ID);
break;
}
memset(hdd_ptr->fn, 0, sizeof(hdd_ptr->fn));
c16stombs(hdd_ptr->fn, hd_file_name, sizeof(hdd_ptr->fn));
strcpy(hd_file_name_multibyte, hdd_ptr->fn);
sector_size = 512;
if (!(existing & 1) && (wcslen(hd_file_name) > 0)) {
if (size > 0x1FFFFFFE00LL) {
settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4105);
return TRUE;
}
img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT);
if (img_format < IMG_FMT_VHD_FIXED) {
f = _wfopen(hd_file_name, L"wb");
} else {
f = (FILE *) 0;
}
if (img_format == IMG_FMT_HDI) { /* HDI file */
if (size >= 0x100000000LL) {
fclose(f);
settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4116, (wchar_t *) IDS_4104);
return TRUE;
}
fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */
fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */
fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */
fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */
fwrite(&sector_size, 1, 4, f); /* 00000010: Sector size in bytes */
fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */
fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */
fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */
for (i = 0; i < 0x3f8; i++)
fwrite(&zero, 1, 4, f);
} else if (img_format == IMG_FMT_HDX) { /* HDX file */
fwrite(&signature, 1, 8, f); /* 00000000: Signature */
fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */
fwrite(&sector_size, 1, 4, f); /* 00000010: Sector size in bytes */
fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */
fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */
fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */
fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */
fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */
} else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */
MVHDGeom _86box_geometry;
block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL;
switch (img_format) {
case IMG_FMT_VHD_FIXED:
vhd_progress_hdlg = hdlg;
_86box_geometry = create_drive_vhd_fixed(hd_file_name_multibyte, tracks, hpc, spt);
break;
case IMG_FMT_VHD_DYNAMIC:
_86box_geometry = create_drive_vhd_dynamic(hd_file_name_multibyte, tracks, hpc, spt, block_size);
break;
case IMG_FMT_VHD_DIFF:
if (file_dlg_w(hdlg, plat_get_string(IDS_4130), L"", plat_get_string(IDS_4131), 0)) {
return TRUE;
}
_86box_geometry = create_drive_vhd_diff(hd_file_name_multibyte, openfilestring, block_size);
break;
}
if (img_format != IMG_FMT_VHD_DIFF)
settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117);
hdd_ptr->tracks = _86box_geometry.cyl;
hdd_ptr->hpc = _86box_geometry.heads;
hdd_ptr->spt = _86box_geometry.spt;
hard_disk_added = 1;
EndDialog(hdlg, 0);
return TRUE;
}
big_buf = (char *) malloc(1048576);
memset(big_buf, 0, 1048576);
r = size >> 20;
size &= 0xfffff;
if (size || r) {
settings_show_window(hdlg, IDT_FILE_NAME, FALSE);
settings_show_window(hdlg, IDC_EDIT_HD_FILE_NAME, FALSE);
settings_show_window(hdlg, IDC_CFILE, FALSE);
settings_show_window(hdlg, IDC_PBAR_IMG_CREATE, TRUE);
settings_enable_window(hdlg, IDT_PROGRESS, TRUE);
h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE);
SendMessage(h, PBM_SETRANGE32, (WPARAM) 0, (LPARAM) r);
SendMessage(h, PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
}
h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE);
if (size) {
if (f) {
fwrite(big_buf, 1, size, f);
}
SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0);
}
if (r) {
for (i = 0; i < r; i++) {
if (f) {
fwrite(big_buf, 1, 1048576, f);
}
SendMessage(h, PBM_SETPOS, (WPARAM) (i + 1), (LPARAM) 0);
settings_process_messages();
}
}
free(big_buf);
if (f) {
fclose(f);
}
settings_msgbox_header(MBX_INFO, (wchar_t *) IDS_4113, (wchar_t *) IDS_4117);
}
hard_disk_added = 1;
EndDialog(hdlg, 0);
return TRUE;
case IDCANCEL:
hard_disk_added = 0;
hdd_ptr->bus = HDD_BUS_DISABLED;
EndDialog(hdlg, 0);
return TRUE;
case IDC_CFILE:
if (!file_dlg_w(hdlg, plat_get_string(IDS_4106), L"", NULL, !(existing & 1))) {
if (!wcschr(wopenfilestring, L'.')) {
if (wcslen(wopenfilestring) && (wcslen(wopenfilestring) <= 256)) {
twcs = &wopenfilestring[wcslen(wopenfilestring)];
twcs[0] = L'.';
twcs[1] = L'i';
twcs[2] = L'm';
twcs[3] = L'g';
}
}
if (!(existing & 1)) {
f = _wfopen(wopenfilestring, L"rb");
if (f != NULL) {
fclose(f);
if (settings_msgbox_ex(MBX_QUESTION_YN, (wchar_t *) IDS_4111, (wchar_t *) IDS_4118, (wchar_t *) IDS_4120, (wchar_t *) IDS_4121, NULL) != 0) /* yes */
return FALSE;
}
}
f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb");
if (f == NULL) {
hdd_add_file_open_error:
fclose(f);
settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108);
return TRUE;
}
if (existing & 1) {
if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) {
fseeko64(f, 0x10, SEEK_SET);
fread(&sector_size, 1, 4, f);
if (sector_size != 512) {
settings_msgbox_header(MBX_ERROR, (wchar_t *) IDS_4119, (wchar_t *) IDS_4109);
fclose(f);
return TRUE;
}
spt = hpc = tracks = 0;
fread(&spt, 1, 4, f);
fread(&hpc, 1, 4, f);
fread(&tracks, 1, 4, f);
} else if (image_is_vhd(openfilestring, 1)) {
fclose(f);
MVHDMeta *vhd = mvhd_open(openfilestring, 0, &vhd_error);
if (vhd == NULL) {
settings_msgbox_header(MBX_ERROR, (existing & 1) ? (wchar_t *) IDS_4114 : (wchar_t *) IDS_4115, (existing & 1) ? (wchar_t *) IDS_4107 : (wchar_t *) IDS_4108);
return TRUE;
} else if (vhd_error == MVHD_ERR_TIMESTAMP) {
if (settings_msgbox_ex(MBX_QUESTION_YN | MBX_WARNING, plat_get_string(IDS_4133), plat_get_string(IDS_4132), NULL, NULL, NULL) != 0) {
int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhd_error);
if (ts_res != 0) {
settings_msgbox_header(MBX_ERROR, plat_get_string(IDS_2049), plat_get_string(IDS_4134));
mvhd_close(vhd);
return TRUE;
}
} else {
mvhd_close(vhd);
return TRUE;
}
}
MVHDGeom vhd_geom = mvhd_get_geometry(vhd);
adjust_vhd_geometry_for_86box(&vhd_geom);
tracks = vhd_geom.cyl;
hpc = vhd_geom.heads;
spt = vhd_geom.spt;
size = (uint64_t) tracks * hpc * spt * 512;
mvhd_close(vhd);
} else {
fseeko64(f, 0, SEEK_END);
size = ftello64(f);
if (((size % 17) == 0) && (size <= 142606336)) {
spt = 17;
if (size <= 26738688)
hpc = 4;
else if (((size % 3072) == 0) && (size <= 53477376))
hpc = 6;
else {
for (i = 5; i < 16; i++) {
if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19)))
break;
if (i == 5)
i++;
}
hpc = i;
}
} else {
spt = 63;
hpc = 16;
}
tracks = ((size >> 9) / hpc) / spt;
}
if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks))
goto hdd_add_file_open_error;
no_update = 1;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20);
recalc_selection(hdlg);
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE);
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE);
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE);
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE);
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE);
chs_enabled = 1;
no_update = 0;
}
fclose(f);
}
h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME);
SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring);
memset(hd_file_name, 0, sizeof(hd_file_name));
wcscpy(hd_file_name, wopenfilestring);
return TRUE;
case IDC_EDIT_HD_CYL:
if (no_update)
return FALSE;
no_update = 1;
get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp);
if (tracks != (int64_t) temp) {
tracks = temp;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (tracks > max_tracks) {
tracks = max_tracks;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
no_update = 0;
break;
case IDC_EDIT_HD_HPC:
if (no_update)
return FALSE;
no_update = 1;
get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp);
if (hpc != (int64_t) temp) {
hpc = temp;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (hpc > max_hpc) {
hpc = max_hpc;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
no_update = 0;
break;
case IDC_EDIT_HD_SPT:
if (no_update)
return FALSE;
no_update = 1;
get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp);
if (spt != (int64_t) temp) {
spt = temp;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (spt > max_spt) {
spt = max_spt;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
no_update = 0;
break;
case IDC_EDIT_HD_SIZE:
if (no_update)
return FALSE;
no_update = 1;
get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp);
if (temp != (uint32_t) (size >> 20)) {
size = ((uint64_t) temp) << 20LL;
/* This is needed to ensure VHD standard compliance. */
hdd_image_calc_chs((uint32_t *) &tracks, (uint32_t *) &hpc, (uint32_t *) &spt, temp);
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt);
recalc_selection(hdlg);
}
if (tracks > max_tracks) {
tracks = max_tracks;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (hpc > max_hpc) {
hpc = max_hpc;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (spt > max_spt) {
spt = max_spt;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
no_update = 0;
break;
case IDC_COMBO_HD_TYPE:
if (no_update)
return FALSE;
no_update = 1;
temp = settings_get_cur_sel(hdlg, IDC_COMBO_HD_TYPE);
if ((temp != selection) && (temp != 127) && (temp != 128)) {
selection = temp;
tracks = hdd_table[selection][0];
hpc = hdd_table[selection][1];
spt = hdd_table[selection][2];
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
} else if ((temp != selection) && (temp == 127))
selection = temp;
else if ((temp != selection) && (temp == 128)) {
selection = temp;
hpc = 16;
spt = 63;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
}
if (spt > max_spt) {
spt = max_spt;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (hpc > max_hpc) {
hpc = max_hpc;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (tracks > max_tracks) {
tracks = max_tracks;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
no_update = 0;
break;
case IDC_COMBO_HD_BUS:
if (no_update)
return FALSE;
no_update = 1;
recalc_location_controls(hdlg, 1, 0);
b = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1;
if (b != hdd_ptr->bus) {
hdd_ptr->bus = b;
switch (hdd_ptr->bus) {
case HDD_BUS_DISABLED:
default:
max_spt = max_hpc = max_tracks = 0;
break;
case HDD_BUS_MFM:
max_spt = 26; /* 17 for MFM, 26 for RLL. */
max_hpc = 15;
max_tracks = 2047;
break;
case HDD_BUS_XTA:
max_spt = 63;
max_hpc = 16;
max_tracks = 1023;
break;
case HDD_BUS_ESDI:
max_spt = 99; /* ESDI drives usually had 32 to 43 sectors per track. */
max_hpc = 16;
max_tracks = 266305;
break;
case HDD_BUS_IDE:
max_spt = 255;
max_hpc = 255;
max_tracks = 266305;
break;
case HDD_BUS_ATAPI:
case HDD_BUS_SCSI:
max_spt = 255;
max_hpc = 255;
max_tracks = 266305;
break;
}
if (!chs_enabled) {
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE);
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE);
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE);
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE);
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE);
}
if (spt > max_spt) {
spt = max_spt;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, (uint32_t) spt);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (hpc > max_hpc) {
hpc = max_hpc;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, (uint32_t) hpc);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
if (tracks > max_tracks) {
tracks = max_tracks;
size = ((uint64_t) tracks * (uint64_t) hpc * (uint64_t) spt) << 9LL;
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, (uint32_t) tracks);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) (size >> 20));
recalc_selection(hdlg);
}
}
no_update = 0;
break;
case IDC_COMBO_HD_IMG_FORMAT:
img_format = settings_get_cur_sel(hdlg, IDC_COMBO_HD_IMG_FORMAT);
no_update = 1;
if (img_format == IMG_FMT_VHD_DIFF) { /* They switched to a diff VHD; disable the geometry fields. */
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, FALSE);
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, L"(N/A)");
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, FALSE);
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_HPC, L"(N/A)");
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, FALSE);
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_CYL, L"(N/A)");
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, FALSE);
set_edit_box_text_contents(hdlg, IDC_EDIT_HD_SIZE, L"(N/A)");
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, FALSE);
settings_reset_content(hdlg, IDC_COMBO_HD_TYPE);
settings_add_string(hdlg, IDC_COMBO_HD_TYPE, (LPARAM) L"(use parent)");
settings_set_cur_sel(hdlg, IDC_COMBO_HD_TYPE, 0);
} else {
get_edit_box_text_contents(hdlg, IDC_EDIT_HD_SPT, text_buf, 256);
if (!wcscmp(text_buf, L"(N/A)")) {
settings_enable_window(hdlg, IDC_EDIT_HD_SPT, TRUE);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17);
spt = 17;
settings_enable_window(hdlg, IDC_EDIT_HD_HPC, TRUE);
set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, 15);
hpc = 15;
settings_enable_window(hdlg, IDC_EDIT_HD_CYL, TRUE);
set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, 1023);
tracks = 1023;
settings_enable_window(hdlg, IDC_EDIT_HD_SIZE, TRUE);
set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (uint32_t) ((uint64_t) 17 * 15 * 1023 * 512 >> 20));
size = (uint64_t) 17 * 15 * 1023 * 512;
settings_reset_content(hdlg, IDC_COMBO_HD_TYPE);
hdconf_initialize_hdt_combo(hdlg);
settings_enable_window(hdlg, IDC_COMBO_HD_TYPE, TRUE);
}
}
no_update = 0;
if (img_format == IMG_FMT_VHD_DYNAMIC || img_format == IMG_FMT_VHD_DIFF) { /* For dynamic and diff VHDs, show the block size dropdown. */
settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, TRUE);
settings_show_window(hdlg, IDT_BLOCK_SIZE, TRUE);
} else { /* Hide it otherwise. */
settings_show_window(hdlg, IDC_COMBO_HD_BLOCK_SIZE, FALSE);
settings_show_window(hdlg, IDT_BLOCK_SIZE, FALSE);
}
break;
}
return FALSE;
}
return FALSE;
}
int
hard_disk_was_added(void)
{
return hard_disk_added;
}
void
hard_disk_add_open(HWND hwnd, int is_existing)
{
existing = is_existing;
hard_disk_added = 0;
DialogBox(hinstance, (LPCWSTR) DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc);
}
static void
hard_disk_track(uint8_t id)
{
switch (temp_hdd[id].bus) {
case HDD_BUS_MFM:
mfm_tracking |= (1 << (temp_hdd[id].mfm_channel << 3));
break;
case HDD_BUS_ESDI:
esdi_tracking |= (1 << (temp_hdd[id].esdi_channel << 3));
break;
case HDD_BUS_XTA:
xta_tracking |= (1 << (temp_hdd[id].xta_channel << 3));
break;
case HDD_BUS_IDE:
case HDD_BUS_ATAPI:
ide_tracking |= (1 << (temp_hdd[id].ide_channel << 3));
break;
case HDD_BUS_SCSI:
scsi_tracking[temp_hdd[id].scsi_id >> 3] |= (1 << ((temp_hdd[id].scsi_id & 0x07) << 3));
break;
}
}
static void
hard_disk_untrack(uint8_t id)
{
switch (temp_hdd[id].bus) {
case HDD_BUS_MFM:
mfm_tracking &= ~(1 << (temp_hdd[id].mfm_channel << 3));
break;
case HDD_BUS_ESDI:
esdi_tracking &= ~(1 << (temp_hdd[id].esdi_channel << 3));
break;
case HDD_BUS_XTA:
xta_tracking &= ~(1 << (temp_hdd[id].xta_channel << 3));
break;
case HDD_BUS_IDE:
case HDD_BUS_ATAPI:
ide_tracking &= ~(1 << (temp_hdd[id].ide_channel << 3));
break;
case HDD_BUS_SCSI:
scsi_tracking[temp_hdd[id].scsi_id >> 3] &= ~(1 << ((temp_hdd[id].scsi_id & 0x07) << 3));
break;
}
}
static void
hard_disk_track_all(void)
{
for (uint8_t i = 0; i < HDD_NUM; i++)
hard_disk_track(i);
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int old_sel = 0;
int b = 0;
int assign = 0;
const uint8_t hd_icons[2] = { 80, 0 };
switch (message) {
case WM_INITDIALOG:
ignore_change = 1;
normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous.
This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list
(which can only happen by manually editing the configuration file). */
win_settings_hard_disks_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_HARD_DISKS, (const uint8_t *) hd_icons);
win_settings_hard_disks_recalc_list(hdlg);
recalc_next_free_id(hdlg);
add_locations(hdlg);
if (hd_listview_items > 0) {
settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, 0);
lv1_current_sel = 0;
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[0].bus - 1);
} else
lv1_current_sel = -1;
recalc_location_controls(hdlg, 0, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_HARD_DISKS);
ignore_change = 0;
return TRUE;
case WM_NOTIFY:
if ((hd_listview_items == 0) || ignore_change)
return FALSE;
if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_HARD_DISKS)) {
old_sel = lv1_current_sel;
lv1_current_sel = get_selected_hard_disk(hdlg);
if (lv1_current_sel == old_sel)
return FALSE;
ignore_change = 1;
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[lv1_current_sel].bus - 1);
recalc_location_controls(hdlg, 0, 0);
ignore_change = 0;
}
break;
case WM_COMMAND:
if (ignore_change && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD) && (LOWORD(wParam) != IDC_BUTTON_HDD_ADD_NEW) && (LOWORD(wParam) != IDC_BUTTON_HDD_REMOVE))
return FALSE;
switch (LOWORD(wParam)) {
case IDC_COMBO_HD_BUS:
ignore_change = 1;
b = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BUS) + 1;
if (b != temp_hdd[lv1_current_sel].bus) {
hard_disk_untrack(lv1_current_sel);
assign = (temp_hdd[lv1_current_sel].bus == b) ? 0 : 1;
temp_hdd[lv1_current_sel].bus = b;
recalc_location_controls(hdlg, 0, assign);
hard_disk_track(lv1_current_sel);
win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0);
}
ignore_change = 0;
return FALSE;
case IDC_COMBO_HD_CHANNEL:
ignore_change = 1;
hard_disk_untrack(lv1_current_sel);
temp_hdd[lv1_current_sel].channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL);
hard_disk_track(lv1_current_sel);
win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0);
ignore_change = 0;
return FALSE;
case IDC_COMBO_HD_CHANNEL_IDE:
ignore_change = 1;
hard_disk_untrack(lv1_current_sel);
temp_hdd[lv1_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_HD_CHANNEL_IDE);
hard_disk_track(lv1_current_sel);
win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0);
ignore_change = 0;
return FALSE;
case IDC_COMBO_HD_ID:
ignore_change = 1;
hard_disk_untrack(lv1_current_sel);
temp_hdd[lv1_current_sel].scsi_id = settings_get_cur_sel(hdlg, IDC_COMBO_HD_ID);
hard_disk_track(lv1_current_sel);
win_settings_hard_disks_update_item(hdlg, lv1_current_sel, 0);
ignore_change = 0;
return FALSE;
case IDC_BUTTON_HDD_ADD:
case IDC_BUTTON_HDD_ADD_NEW:
hard_disk_add_open(hdlg, (LOWORD(wParam) == IDC_BUTTON_HDD_ADD));
if (hard_disk_added) {
ignore_change = 1;
win_settings_hard_disks_recalc_list(hdlg);
recalc_next_free_id(hdlg);
hard_disk_track_all();
ignore_change = 0;
}
return FALSE;
case IDC_BUTTON_HDD_REMOVE:
temp_hdd[lv1_current_sel].fn[0] = '\0';
hard_disk_untrack(lv1_current_sel);
temp_hdd[lv1_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */
normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */
ignore_change = 1;
win_settings_hard_disks_recalc_list(hdlg);
recalc_next_free_id(hdlg);
if (hd_listview_items > 0) {
settings_listview_select(hdlg, IDC_LIST_HARD_DISKS, 0);
lv1_current_sel = 0;
settings_set_cur_sel(hdlg, IDC_COMBO_HD_BUS, temp_hdd[0].bus - 1);
} else
lv1_current_sel = -1;
recalc_location_controls(hdlg, 0, 0);
ignore_change = 0;
return FALSE;
}
case WM_DPICHANGED_AFTERPARENT:
win_settings_hard_disks_resize_columns(hdlg);
image_list_init(hdlg, IDC_LIST_HARD_DISKS, (const uint8_t *) hd_icons);
break;
default:
return FALSE;
}
return FALSE;
}
static int
combo_id_to_string_id(int combo_id)
{
return IDS_5376 + combo_id;
}
static int
combo_id_to_format_string_id(int combo_id)
{
return IDS_5632 + combo_id;
}
static BOOL
win_settings_floppy_drives_recalc_list(HWND hdlg)
{
LVITEM lvI;
char s[256];
char *t;
WCHAR szText[256];
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.state = 0;
for (uint8_t i = 0; i < FDD_NUM; i++) {
lvI.iSubItem = 0;
if (temp_fdd_types[i] > 0) {
t = fdd_getname(temp_fdd_types[i]);
strncpy(s, t, sizeof(s) - 1);
mbstowcs(szText, s, strlen(s) + 1);
lvI.pszText = szText;
} else
lvI.pszText = plat_get_string(IDS_5376);
lvI.iItem = i;
lvI.iImage = temp_fdd_types[i];
if (ListView_InsertItem(hwndList, &lvI) == -1)
return FALSE;
lvI.iSubItem = 1;
lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
}
return TRUE;
}
static BOOL
win_settings_cdrom_drives_recalc_list(HWND hdlg)
{
LVITEM lvI;
int fsid = 0;
WCHAR szText[256];
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
for (uint8_t i = 0; i < CDROM_NUM; i++) {
fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type);
lvI.iSubItem = 0;
switch (temp_cdrom[i].bus_type) {
case CDROM_BUS_DISABLED:
default:
lvI.pszText = plat_get_string(fsid);
lvI.iImage = 0;
break;
case CDROM_BUS_ATAPI:
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].ide_channel >> 1, temp_cdrom[i].ide_channel & 1);
lvI.pszText = szText;
lvI.iImage = 1;
break;
case CDROM_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
}
lvI.iItem = i;
if (ListView_InsertItem(hwndList, &lvI) == -1)
return FALSE;
lvI.iSubItem = 1;
if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED)
lvI.pszText = plat_get_string(IDS_2104);
else {
wsprintf(szText, L"%ix", temp_cdrom[i].speed);
lvI.pszText = szText;
}
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
/*
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
*/
}
return TRUE;
}
static BOOL
win_settings_mo_drives_recalc_list(HWND hdlg)
{
LVITEM lvI;
int fsid = 0;
WCHAR szText[256];
char szType[30];
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
for (uint8_t i = 0; i < MO_NUM; i++) {
fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type);
lvI.iSubItem = 0;
switch (temp_mo_drives[i].bus_type) {
case MO_BUS_DISABLED:
default:
lvI.pszText = plat_get_string(fsid);
lvI.iImage = 0;
break;
case MO_BUS_ATAPI:
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].ide_channel >> 1, temp_mo_drives[i].ide_channel & 1);
lvI.pszText = szText;
lvI.iImage = 1;
break;
case MO_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
}
lvI.iItem = i;
if (ListView_InsertItem(hwndList, &lvI) == -1)
return FALSE;
lvI.iSubItem = 1;
if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED)
lvI.pszText = plat_get_string(IDS_2104);
else {
memset(szType, 0, 30);
memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8);
szType[strlen(szType)] = ' ';
memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].model, 16);
szType[strlen(szType)] = ' ';
memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].revision, 4);
mbstowcs(szText, szType, strlen(szType) + 1);
lvI.pszText = szText;
}
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
}
return TRUE;
}
static BOOL
win_settings_zip_drives_recalc_list(HWND hdlg)
{
LVITEM lvI;
int fsid = 0;
WCHAR szText[256];
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
for (uint8_t i = 0; i < ZIP_NUM; i++) {
fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type);
lvI.iSubItem = 0;
switch (temp_zip_drives[i].bus_type) {
case ZIP_BUS_DISABLED:
default:
lvI.pszText = plat_get_string(fsid);
lvI.iImage = 0;
break;
case ZIP_BUS_ATAPI:
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1);
lvI.pszText = szText;
lvI.iImage = 1;
break;
case ZIP_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
}
lvI.iItem = i;
if (ListView_InsertItem(hwndList, &lvI) == -1)
return FALSE;
lvI.iSubItem = 1;
lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return FALSE;
}
return TRUE;
}
#define C_COLUMNS_FLOPPY_DRIVES_TYPE 292
#define C_COLUMNS_FLOPPY_DRIVES_TURBO 58
#define C_COLUMNS_FLOPPY_DRIVES_BPB 89
static void
win_settings_floppy_drives_resize_columns(HWND hdlg)
{
int width[C_COLUMNS_FLOPPY_DRIVES] = {
C_COLUMNS_FLOPPY_DRIVES_TYPE,
C_COLUMNS_FLOPPY_DRIVES_TURBO,
C_COLUMNS_FLOPPY_DRIVES_BPB
};
int total = 0;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES);
RECT r;
GetWindowRect(hwndList, &r);
for (uint8_t iCol = 0; iCol < C_COLUMNS_FLOPPY_DRIVES; iCol++) {
width[iCol] = MulDiv(width[iCol], dpi, 96);
total += width[iCol];
ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96));
}
width[C_COLUMNS_FLOPPY_DRIVES - 1] = (r.right - r.left) - 4 - total;
ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_FLOPPY_DRIVES - 1]);
}
static BOOL
win_settings_floppy_drives_init_columns(HWND hdlg)
{
LVCOLUMN lvc;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
/* Type */
lvc.iSubItem = 0;
lvc.pszText = plat_get_string(IDS_TYPE);
lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TYPE;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 0, &lvc) == -1)
return FALSE;
/* Turbo */
lvc.iSubItem = 1;
lvc.pszText = plat_get_string(IDS_2059);
lvc.cx = C_COLUMNS_FLOPPY_DRIVES_TURBO;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
/* Check BPB */
lvc.iSubItem = 2;
lvc.pszText = plat_get_string(IDS_BPB);
lvc.cx = C_COLUMNS_FLOPPY_DRIVES_BPB;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 2, &lvc) == -1)
return FALSE;
win_settings_floppy_drives_resize_columns(hdlg);
return TRUE;
}
#define C_COLUMNS_CDROM_DRIVES_BUS 292
#define C_COLUMNS_CDROM_DRIVES_SPEED 58
#define C_COLUMNS_CDROM_DRIVES_EARLIER 89
static void
win_settings_cdrom_drives_resize_columns(HWND hdlg)
{
int width[C_COLUMNS_CDROM_DRIVES] = {
C_COLUMNS_CDROM_DRIVES_BUS,
C_COLUMNS_CDROM_DRIVES_SPEED,
C_COLUMNS_CDROM_DRIVES_EARLIER
};
int total = 0;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES);
RECT r;
GetWindowRect(hwndList, &r);
for (uint8_t iCol = 0; iCol < C_COLUMNS_CDROM_DRIVES; iCol++) {
width[iCol] = MulDiv(width[iCol], dpi, 96);
total += width[iCol];
ListView_SetColumnWidth(hwndList, iCol, MulDiv(width[iCol], dpi, 96));
}
width[C_COLUMNS_CDROM_DRIVES - 1] = (r.right - r.left) - 4 - total;
ListView_SetColumnWidth(hwndList, 2, width[C_COLUMNS_CDROM_DRIVES - 1]);
}
static BOOL
win_settings_cdrom_drives_init_columns(HWND hdlg)
{
LVCOLUMN lvc;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
/* Bus */
lvc.iSubItem = 0;
lvc.pszText = plat_get_string(IDS_BUS);
lvc.cx = C_COLUMNS_CDROM_DRIVES_BUS;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 0, &lvc) == -1)
return FALSE;
/* Speed */
lvc.iSubItem = 1;
lvc.pszText = plat_get_string(IDS_2053);
lvc.cx = C_COLUMNS_CDROM_DRIVES_SPEED;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
/* Type */
lvc.iSubItem = 2;
lvc.pszText = plat_get_string(IDS_2162);
lvc.cx = C_COLUMNS_CDROM_DRIVES_EARLIER;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 2, &lvc) == -1)
return FALSE;
win_settings_cdrom_drives_resize_columns(hdlg);
return TRUE;
}
#define C_COLUMNS_MO_DRIVES_BUS 292
#define C_COLUMNS_MO_DRIVES_TYPE 147
static void
win_settings_mo_drives_resize_columns(HWND hdlg)
{
int width[C_COLUMNS_MO_DRIVES] = {
C_COLUMNS_MO_DRIVES_BUS,
C_COLUMNS_MO_DRIVES_TYPE
};
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES);
RECT r;
GetWindowRect(hwndList, &r);
width[0] = MulDiv(width[0], dpi, 96);
ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96));
width[C_COLUMNS_MO_DRIVES - 1] = (r.right - r.left) - 4 - width[0];
ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_MO_DRIVES - 1]);
}
static BOOL
win_settings_mo_drives_init_columns(HWND hdlg)
{
LVCOLUMN lvc;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
/* Bus */
lvc.iSubItem = 0;
lvc.pszText = plat_get_string(IDS_BUS);
lvc.cx = C_COLUMNS_MO_DRIVES_BUS;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 0, &lvc) == -1)
return FALSE;
/* Type */
lvc.iSubItem = 1;
lvc.pszText = plat_get_string(IDS_TYPE);
lvc.cx = C_COLUMNS_MO_DRIVES_TYPE;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
win_settings_mo_drives_resize_columns(hdlg);
return TRUE;
}
#define C_COLUMNS_ZIP_DRIVES_BUS 292
#define C_COLUMNS_ZIP_DRIVES_TYPE 147
static void
win_settings_zip_drives_resize_columns(HWND hdlg)
{
int width[C_COLUMNS_MO_DRIVES] = {
C_COLUMNS_ZIP_DRIVES_BUS,
C_COLUMNS_ZIP_DRIVES_TYPE
};
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES);
RECT r;
GetWindowRect(hwndList, &r);
width[0] = MulDiv(width[0], dpi, 96);
ListView_SetColumnWidth(hwndList, 0, MulDiv(width[0], dpi, 96));
width[C_COLUMNS_ZIP_DRIVES - 1] = (r.right - r.left) - 4 - width[0];
ListView_SetColumnWidth(hwndList, 1, width[C_COLUMNS_ZIP_DRIVES - 1]);
}
static BOOL
win_settings_zip_drives_init_columns(HWND hdlg)
{
LVCOLUMN lvc;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
/* Bus */
lvc.iSubItem = 0;
lvc.pszText = plat_get_string(IDS_BUS);
lvc.cx = C_COLUMNS_ZIP_DRIVES_BUS;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 0, &lvc) == -1)
return FALSE;
/* Type */
lvc.iSubItem = 1;
lvc.pszText = plat_get_string(IDS_TYPE);
lvc.cx = C_COLUMNS_ZIP_DRIVES_TYPE;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
return FALSE;
win_settings_zip_drives_resize_columns(hdlg);
return TRUE;
}
static int
get_selected_drive(HWND hdlg, int id, int max)
{
int drive = -1;
int j = 0;
HWND h;
for (int i = 0; i < max; i++) {
h = GetDlgItem(hdlg, id);
j = ListView_GetItemState(h, i, LVIS_SELECTED);
if (j)
drive = i;
}
return drive;
}
static void
win_settings_floppy_drives_update_item(HWND hdlg, int i)
{
LVITEM lvI;
char s[256];
char *t;
WCHAR szText[256];
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
lvI.iSubItem = 0;
lvI.iItem = i;
if (temp_fdd_types[i] > 0) {
t = fdd_getname(temp_fdd_types[i]);
strncpy(s, t, sizeof(s) - 1);
mbstowcs(szText, s, strlen(s) + 1);
lvI.pszText = szText;
} else
lvI.pszText = plat_get_string(IDS_5376);
lvI.iImage = temp_fdd_types[i];
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
lvI.iSubItem = 1;
lvI.pszText = plat_get_string(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
}
static void
win_settings_cdrom_drives_update_item(HWND hdlg, int i)
{
LVITEM lvI;
WCHAR szText[256];
int fsid;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
lvI.iSubItem = 0;
lvI.iItem = i;
fsid = combo_id_to_format_string_id(temp_cdrom[i].bus_type);
switch (temp_cdrom[i].bus_type) {
case CDROM_BUS_DISABLED:
default:
lvI.pszText = plat_get_string(fsid);
lvI.iImage = 0;
break;
case CDROM_BUS_ATAPI:
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].ide_channel >> 1, temp_cdrom[i].ide_channel & 1);
lvI.pszText = szText;
lvI.iImage = 1;
break;
case CDROM_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_cdrom[i].scsi_device_id >> 4, temp_cdrom[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
}
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
lvI.iSubItem = 1;
if (temp_cdrom[i].bus_type == CDROM_BUS_DISABLED)
lvI.pszText = plat_get_string(IDS_2104);
else {
wsprintf(szText, L"%ix", temp_cdrom[i].speed);
lvI.pszText = szText;
}
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
/*
lvI.iSubItem = 2;
lvI.pszText = plat_get_string(temp_cdrom[i].early ? IDS_2060 : IDS_2061);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
*/
}
static void
win_settings_mo_drives_update_item(HWND hdlg, int i)
{
LVITEM lvI;
WCHAR szText[256];
char szType[30];
int fsid;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_MO_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
/* Bus */
lvI.iSubItem = 0;
lvI.iItem = i;
fsid = combo_id_to_format_string_id(temp_mo_drives[i].bus_type);
switch (temp_mo_drives[i].bus_type) {
case MO_BUS_DISABLED:
default:
lvI.pszText = plat_get_string(fsid);
lvI.iImage = 0;
break;
case MO_BUS_ATAPI:
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].ide_channel >> 1, temp_mo_drives[i].ide_channel & 1);
lvI.pszText = szText;
lvI.iImage = 1;
break;
case MO_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_mo_drives[i].scsi_device_id >> 4, temp_mo_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
}
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
/* Type */
lvI.iSubItem = 1;
if (temp_mo_drives[i].bus_type == MO_BUS_DISABLED)
lvI.pszText = plat_get_string(IDS_2104);
else {
memset(szType, 0, 30);
memcpy(szType, mo_drive_types[temp_mo_drives[i].type].vendor, 8);
szType[strlen(szType)] = ' ';
memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].model, 16);
szType[strlen(szType)] = ' ';
memcpy(szType + strlen(szType), mo_drive_types[temp_mo_drives[i].type].revision, 4);
mbstowcs(szText, szType, strlen(szType) + 1);
lvI.pszText = szText;
}
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
}
static void
win_settings_zip_drives_update_item(HWND hdlg, int i)
{
LVITEM lvI;
WCHAR szText[256];
int fsid;
HWND hwndList = GetDlgItem(hdlg, IDC_LIST_ZIP_DRIVES);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
lvI.iSubItem = 0;
lvI.iItem = i;
fsid = combo_id_to_format_string_id(temp_zip_drives[i].bus_type);
switch (temp_zip_drives[i].bus_type) {
case ZIP_BUS_DISABLED:
default:
lvI.pszText = plat_get_string(fsid);
lvI.iImage = 0;
break;
case ZIP_BUS_ATAPI:
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].ide_channel >> 1, temp_zip_drives[i].ide_channel & 1);
lvI.pszText = szText;
lvI.iImage = 1;
break;
case ZIP_BUS_SCSI:
wsprintf(szText, plat_get_string(fsid), temp_zip_drives[i].scsi_device_id >> 4, temp_zip_drives[i].scsi_device_id & 15);
lvI.pszText = szText;
lvI.iImage = 1;
break;
}
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
lvI.iSubItem = 1;
lvI.pszText = plat_get_string(temp_zip_drives[i].is_250 ? IDS_5901 : IDS_5900);
lvI.iItem = i;
lvI.iImage = 0;
if (ListView_SetItem(hwndList, &lvI) == -1)
return;
}
static void
cdrom_add_locations(HWND hdlg)
{
LPTSTR lptsTemp;
int i = 0;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) {
if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI))
settings_add_string(hdlg, IDC_COMBO_CD_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 1; i <= 72; i++) {
wsprintf(lptsTemp, L"%ix", i);
settings_add_string(hdlg, IDC_COMBO_CD_SPEED, (LPARAM) lptsTemp);
}
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_CD_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_CD_CHANNEL_IDE, (LPARAM) lptsTemp);
}
free(lptsTemp);
}
static void
cdrom_recalc_location_controls(HWND hdlg, int assign_id)
{
int bus = temp_cdrom[lv2_current_sel].bus_type;
for (uint16_t i = IDT_CD_ID; i <= IDT_CD_CHANNEL; i++)
settings_show_window(hdlg, i, FALSE);
settings_show_window(hdlg, IDC_COMBO_CD_ID, FALSE);
settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, FALSE);
settings_show_window(hdlg, IDC_COMBO_CD_SPEED, bus != CDROM_BUS_DISABLED);
settings_show_window(hdlg, IDT_CD_SPEED, bus != CDROM_BUS_DISABLED);
/*
settings_show_window(hdlg, IDC_CHECKEARLY, bus != CDROM_BUS_DISABLED);
*/
if (bus != CDROM_BUS_DISABLED) {
settings_set_cur_sel(hdlg, IDC_COMBO_CD_SPEED, temp_cdrom[lv2_current_sel].speed - 1);
// settings_set_check(hdlg, IDC_CHECKEARLY, temp_cdrom[lv2_current_sel].early);
}
switch (bus) {
case CDROM_BUS_ATAPI: /* ATAPI */
settings_show_window(hdlg, IDT_CD_CHANNEL, TRUE);
settings_show_window(hdlg, IDC_COMBO_CD_CHANNEL_IDE, TRUE);
if (assign_id)
temp_cdrom[lv2_current_sel].ide_channel = next_free_ide_channel();
settings_set_cur_sel(hdlg, IDC_COMBO_CD_CHANNEL_IDE, temp_cdrom[lv2_current_sel].ide_channel);
break;
case CDROM_BUS_SCSI: /* SCSI */
settings_show_window(hdlg, IDT_CD_ID, TRUE);
settings_show_window(hdlg, IDC_COMBO_CD_ID, TRUE);
if (assign_id)
next_free_scsi_id((uint8_t *) &temp_cdrom[lv2_current_sel].scsi_device_id);
settings_set_cur_sel(hdlg, IDC_COMBO_CD_ID, temp_cdrom[lv2_current_sel].scsi_device_id);
break;
}
}
static void
mo_add_locations(HWND hdlg)
{
LPTSTR lptsTemp;
char *temp;
int i = 0;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
temp = (char *) malloc(30 * sizeof(char));
for (i = MO_BUS_DISABLED; i <= MO_BUS_SCSI; i++) {
if ((i == MO_BUS_DISABLED) || (i >= MO_BUS_ATAPI))
settings_add_string(hdlg, IDC_COMBO_MO_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 0; i < (SCSI_BUS_MAX * SCSI_ID_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_MO_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_MO_CHANNEL_IDE, (LPARAM) lptsTemp);
}
for (int i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) {
memset(temp, 0, 30);
memcpy(temp, mo_drive_types[i].vendor, 8);
temp[strlen(temp)] = ' ';
memcpy(temp + strlen(temp), mo_drive_types[i].model, 16);
temp[strlen(temp)] = ' ';
memcpy(temp + strlen(temp), mo_drive_types[i].revision, 4);
mbstowcs(lptsTemp, temp, strlen(temp) + 1);
settings_add_string(hdlg, IDC_COMBO_MO_TYPE, (LPARAM) lptsTemp);
}
free(temp);
free(lptsTemp);
}
static void
mo_recalc_location_controls(HWND hdlg, int assign_id)
{
int bus = temp_mo_drives[lv1_current_sel].bus_type;
for (int i = IDT_MO_ID; i <= IDT_MO_CHANNEL; i++)
settings_show_window(hdlg, i, FALSE);
settings_show_window(hdlg, IDC_COMBO_MO_ID, FALSE);
settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, FALSE);
settings_show_window(hdlg, IDC_COMBO_MO_TYPE, bus != MO_BUS_DISABLED);
settings_show_window(hdlg, IDT_MO_TYPE, bus != MO_BUS_DISABLED);
if (bus != MO_BUS_DISABLED)
settings_set_cur_sel(hdlg, IDC_COMBO_MO_TYPE, temp_mo_drives[lv1_current_sel].type);
switch (bus) {
case MO_BUS_ATAPI: /* ATAPI */
settings_show_window(hdlg, IDT_MO_CHANNEL, TRUE);
settings_show_window(hdlg, IDC_COMBO_MO_CHANNEL_IDE, TRUE);
if (assign_id)
temp_mo_drives[lv1_current_sel].ide_channel = next_free_ide_channel();
settings_set_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE, temp_mo_drives[lv1_current_sel].ide_channel);
break;
case MO_BUS_SCSI: /* SCSI */
settings_show_window(hdlg, IDT_MO_ID, TRUE);
settings_show_window(hdlg, IDC_COMBO_MO_ID, TRUE);
if (assign_id)
next_free_scsi_id((uint8_t *) &temp_mo_drives[lv1_current_sel].scsi_device_id);
settings_set_cur_sel(hdlg, IDC_COMBO_MO_ID, temp_mo_drives[lv1_current_sel].scsi_device_id);
break;
}
}
static void
zip_add_locations(HWND hdlg)
{
LPTSTR lptsTemp;
int i = 0;
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
for (i = ZIP_BUS_DISABLED; i <= ZIP_BUS_SCSI; i++) {
if ((i == ZIP_BUS_DISABLED) || (i >= ZIP_BUS_ATAPI))
settings_add_string(hdlg, IDC_COMBO_ZIP_BUS, win_get_string(combo_id_to_string_id(i)));
}
for (i = 0; i < (SCSI_BUS_MAX * SCSI_LUN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4135), i >> 4, i & 15);
settings_add_string(hdlg, IDC_COMBO_ZIP_ID, (LPARAM) lptsTemp);
}
for (i = 0; i < (IDE_BUS_MAX * IDE_CHAN_MAX); i++) {
wsprintf(lptsTemp, plat_get_string(IDS_4097), i >> 1, i & 1);
settings_add_string(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, (LPARAM) lptsTemp);
}
free(lptsTemp);
}
static void
zip_recalc_location_controls(HWND hdlg, int assign_id)
{
int bus = temp_zip_drives[lv2_current_sel].bus_type;
for (int i = IDT_ZIP_ID; i <= IDT_ZIP_LUN; i++)
settings_show_window(hdlg, i, FALSE);
settings_show_window(hdlg, IDC_COMBO_ZIP_ID, FALSE);
settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, FALSE);
settings_show_window(hdlg, IDC_CHECK250, bus != ZIP_BUS_DISABLED);
if (bus != ZIP_BUS_DISABLED)
settings_set_check(hdlg, IDC_CHECK250, temp_zip_drives[lv2_current_sel].is_250);
switch (bus) {
case ZIP_BUS_ATAPI: /* ATAPI */
settings_show_window(hdlg, IDT_ZIP_LUN, TRUE);
settings_show_window(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, TRUE);
if (assign_id)
temp_zip_drives[lv2_current_sel].ide_channel = next_free_ide_channel();
settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE, temp_zip_drives[lv2_current_sel].ide_channel);
break;
case ZIP_BUS_SCSI: /* SCSI */
settings_show_window(hdlg, IDT_ZIP_ID, TRUE);
settings_show_window(hdlg, IDC_COMBO_ZIP_ID, TRUE);
if (assign_id)
next_free_scsi_id((uint8_t *) &temp_zip_drives[lv2_current_sel].scsi_device_id);
settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_ID, temp_zip_drives[lv2_current_sel].scsi_device_id);
break;
}
}
static void
cdrom_track(uint8_t id)
{
if (temp_cdrom[id].bus_type == CDROM_BUS_ATAPI)
ide_tracking |= (2 << (temp_cdrom[id].ide_channel << 3));
else if (temp_cdrom[id].bus_type == CDROM_BUS_SCSI)
scsi_tracking[temp_cdrom[id].scsi_device_id >> 3] |= (1 << (temp_cdrom[id].scsi_device_id & 0x07));
}
static void
cdrom_untrack(uint8_t id)
{
if (temp_cdrom[id].bus_type == CDROM_BUS_ATAPI)
ide_tracking &= ~(2 << (temp_cdrom[id].ide_channel << 3));
else if (temp_cdrom[id].bus_type == CDROM_BUS_SCSI)
scsi_tracking[temp_cdrom[id].scsi_device_id >> 3] &= ~(1 << (temp_cdrom[id].scsi_device_id & 0x07));
}
static void
zip_track(uint8_t id)
{
if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI)
ide_tracking |= (1 << temp_zip_drives[id].ide_channel);
else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI)
scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] |= (1 << (temp_zip_drives[id].scsi_device_id & 0x07));
}
static void
zip_untrack(uint8_t id)
{
if (temp_zip_drives[id].bus_type == ZIP_BUS_ATAPI)
ide_tracking &= ~(1 << temp_zip_drives[id].ide_channel);
else if (temp_zip_drives[id].bus_type == ZIP_BUS_SCSI)
scsi_tracking[temp_zip_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_zip_drives[id].scsi_device_id & 0x07));
}
static void
mo_track(uint8_t id)
{
if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI)
ide_tracking |= (1 << (temp_zip_drives[id].ide_channel << 3));
else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI)
scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] |= (1 << (temp_mo_drives[id].scsi_device_id & 0x07));
}
static void
mo_untrack(uint8_t id)
{
if (temp_mo_drives[id].bus_type == MO_BUS_ATAPI)
ide_tracking &= ~(1 << (temp_zip_drives[id].ide_channel << 3));
else if (temp_mo_drives[id].bus_type == MO_BUS_SCSI)
scsi_tracking[temp_mo_drives[id].scsi_device_id >> 3] &= ~(1 << (temp_mo_drives[id].scsi_device_id & 0x07));
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_floppy_and_cdrom_drives_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int old_sel = 0;
int b = 0;
int assign = 0;
uint32_t b2 = 0;
WCHAR szText[256];
const uint8_t fd_icons[15] = { 248, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 0 };
const uint8_t cd_icons[3] = { 249, 32, 0 };
switch (message) {
case WM_INITDIALOG:
ignore_change = 1;
lv1_current_sel = 0;
win_settings_floppy_drives_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_FLOPPY_DRIVES, (const uint8_t *) fd_icons);
win_settings_floppy_drives_recalc_list(hdlg);
settings_listview_select(hdlg, IDC_LIST_FLOPPY_DRIVES, 0);
for (uint8_t i = 0; i < 14; i++) {
if (i == 0)
settings_add_string(hdlg, IDC_COMBO_FD_TYPE, win_get_string(IDS_5376));
else {
mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1);
settings_add_string(hdlg, IDC_COMBO_FD_TYPE, (LPARAM) szText);
}
}
settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]);
settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]);
settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]);
settings_listview_enable_styles(hdlg, IDC_LIST_FLOPPY_DRIVES);
lv2_current_sel = 0;
win_settings_cdrom_drives_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons);
win_settings_cdrom_drives_recalc_list(hdlg);
settings_listview_select(hdlg, IDC_LIST_CDROM_DRIVES, 0);
cdrom_add_locations(hdlg);
switch (temp_cdrom[lv2_current_sel].bus_type) {
case CDROM_BUS_DISABLED:
default:
b = 0;
break;
case CDROM_BUS_ATAPI:
b = 1;
break;
case CDROM_BUS_SCSI:
b = 2;
break;
}
settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b);
cdrom_recalc_location_controls(hdlg, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_CDROM_DRIVES);
ignore_change = 0;
return TRUE;
case WM_NOTIFY:
if (ignore_change)
return FALSE;
if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) {
old_sel = lv1_current_sel;
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_FLOPPY_DRIVES, FDD_NUM);
if (lv1_current_sel == old_sel)
return FALSE;
ignore_change = 1;
settings_set_cur_sel(hdlg, IDC_COMBO_FD_TYPE, temp_fdd_types[lv1_current_sel]);
settings_set_check(hdlg, IDC_CHECKTURBO, temp_fdd_turbo[lv1_current_sel]);
settings_set_check(hdlg, IDC_CHECKBPB, temp_fdd_check_bpb[lv1_current_sel]);
ignore_change = 0;
} else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) {
old_sel = lv2_current_sel;
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_CDROM_DRIVES, CDROM_NUM);
if (lv2_current_sel == old_sel)
return FALSE;
ignore_change = 1;
switch (temp_cdrom[lv2_current_sel].bus_type) {
case CDROM_BUS_DISABLED:
default:
b = 0;
break;
case CDROM_BUS_ATAPI:
b = 1;
break;
case CDROM_BUS_SCSI:
b = 2;
break;
}
settings_set_cur_sel(hdlg, IDC_COMBO_CD_BUS, b);
cdrom_recalc_location_controls(hdlg, 0);
ignore_change = 0;
}
break;
case WM_COMMAND:
if (ignore_change)
return FALSE;
ignore_change = 1;
switch (LOWORD(wParam)) {
case IDC_COMBO_FD_TYPE:
temp_fdd_types[lv1_current_sel] = settings_get_cur_sel(hdlg, IDC_COMBO_FD_TYPE);
win_settings_floppy_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_CHECKTURBO:
temp_fdd_turbo[lv1_current_sel] = settings_get_check(hdlg, IDC_CHECKTURBO);
win_settings_floppy_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_CHECKBPB:
temp_fdd_check_bpb[lv1_current_sel] = settings_get_check(hdlg, IDC_CHECKBPB);
win_settings_floppy_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_COMBO_CD_BUS:
b = settings_get_cur_sel(hdlg, IDC_COMBO_CD_BUS);
switch (b) {
case 0:
b2 = CDROM_BUS_DISABLED;
break;
case 1:
b2 = CDROM_BUS_ATAPI;
break;
case 2:
b2 = CDROM_BUS_SCSI;
break;
}
if (b2 == temp_cdrom[lv2_current_sel].bus_type)
break;
cdrom_untrack(lv2_current_sel);
assign = (temp_cdrom[lv2_current_sel].bus_type == b2) ? 0 : 1;
if (temp_cdrom[lv2_current_sel].bus_type == CDROM_BUS_DISABLED)
temp_cdrom[lv2_current_sel].speed = 8;
temp_cdrom[lv2_current_sel].bus_type = b2;
cdrom_recalc_location_controls(hdlg, assign);
cdrom_track(lv2_current_sel);
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
case IDC_COMBO_CD_ID:
cdrom_untrack(lv2_current_sel);
temp_cdrom[lv2_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_CD_ID);
cdrom_track(lv2_current_sel);
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
case IDC_COMBO_CD_CHANNEL_IDE:
cdrom_untrack(lv2_current_sel);
temp_cdrom[lv2_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_CD_CHANNEL_IDE);
cdrom_track(lv2_current_sel);
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
case IDC_COMBO_CD_SPEED:
temp_cdrom[lv2_current_sel].speed = settings_get_cur_sel(hdlg, IDC_COMBO_CD_SPEED) + 1;
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
/*
case IDC_CHECKEARLY:
temp_cdrom[lv2_current_sel].early = settings_get_check(hdlg, IDC_CHECKEARLY);
win_settings_cdrom_drives_update_item(hdlg, lv2_current_sel);
break;
*/
}
ignore_change = 0;
case WM_DPICHANGED_AFTERPARENT:
win_settings_floppy_drives_resize_columns(hdlg);
image_list_init(hdlg, IDC_LIST_FLOPPY_DRIVES, (const uint8_t *) fd_icons);
win_settings_cdrom_drives_resize_columns(hdlg);
image_list_init(hdlg, IDC_LIST_CDROM_DRIVES, (const uint8_t *) cd_icons);
break;
default:
return FALSE;
}
return FALSE;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_other_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int old_sel = 0;
int b = 0;
int assign = 0;
uint32_t b2 = 0;
const uint8_t mo_icons[3] = { 251, 56, 0 };
const uint8_t zip_icons[3] = { 250, 48, 0 };
switch (message) {
case WM_INITDIALOG:
ignore_change = 1;
lv1_current_sel = 0;
win_settings_mo_drives_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_MO_DRIVES, (const uint8_t *) mo_icons);
win_settings_mo_drives_recalc_list(hdlg);
settings_listview_select(hdlg, IDC_LIST_MO_DRIVES, 0);
mo_add_locations(hdlg);
switch (temp_mo_drives[lv1_current_sel].bus_type) {
case MO_BUS_DISABLED:
default:
b = 0;
break;
case MO_BUS_ATAPI:
b = 1;
break;
case MO_BUS_SCSI:
b = 2;
break;
}
settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b);
mo_recalc_location_controls(hdlg, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_MO_DRIVES);
lv2_current_sel = 0;
win_settings_zip_drives_init_columns(hdlg);
image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons);
win_settings_zip_drives_recalc_list(hdlg);
settings_listview_select(hdlg, IDC_LIST_ZIP_DRIVES, 0);
zip_add_locations(hdlg);
switch (temp_zip_drives[lv2_current_sel].bus_type) {
case ZIP_BUS_DISABLED:
default:
b = 0;
break;
case ZIP_BUS_ATAPI:
b = 1;
break;
case ZIP_BUS_SCSI:
b = 2;
break;
}
settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b);
zip_recalc_location_controls(hdlg, 0);
settings_listview_enable_styles(hdlg, IDC_LIST_ZIP_DRIVES);
ignore_change = 0;
return TRUE;
case WM_NOTIFY:
if (ignore_change)
return FALSE;
if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_MO_DRIVES)) {
old_sel = lv1_current_sel;
lv1_current_sel = get_selected_drive(hdlg, IDC_LIST_MO_DRIVES, MO_NUM);
if (lv1_current_sel == old_sel)
return FALSE;
ignore_change = 1;
switch (temp_mo_drives[lv1_current_sel].bus_type) {
case MO_BUS_DISABLED:
default:
b = 0;
break;
case MO_BUS_ATAPI:
b = 1;
break;
case MO_BUS_SCSI:
b = 2;
break;
}
settings_set_cur_sel(hdlg, IDC_COMBO_MO_BUS, b);
mo_recalc_location_controls(hdlg, 0);
ignore_change = 0;
} else if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_LIST_ZIP_DRIVES)) {
old_sel = lv2_current_sel;
lv2_current_sel = get_selected_drive(hdlg, IDC_LIST_ZIP_DRIVES, ZIP_NUM);
if (lv2_current_sel == old_sel)
return FALSE;
ignore_change = 1;
switch (temp_zip_drives[lv2_current_sel].bus_type) {
case ZIP_BUS_DISABLED:
default:
b = 0;
break;
case ZIP_BUS_ATAPI:
b = 1;
break;
case ZIP_BUS_SCSI:
b = 2;
break;
}
settings_set_cur_sel(hdlg, IDC_COMBO_ZIP_BUS, b);
zip_recalc_location_controls(hdlg, 0);
ignore_change = 0;
}
break;
case WM_COMMAND:
if (ignore_change)
return FALSE;
ignore_change = 1;
switch (LOWORD(wParam)) {
case IDC_COMBO_MO_BUS:
b = settings_get_cur_sel(hdlg, IDC_COMBO_MO_BUS);
switch (b) {
case 0:
b2 = MO_BUS_DISABLED;
break;
case 1:
b2 = MO_BUS_ATAPI;
break;
case 2:
b2 = MO_BUS_SCSI;
break;
}
if (b2 == temp_mo_drives[lv1_current_sel].bus_type)
break;
mo_untrack(lv1_current_sel);
assign = (temp_mo_drives[lv1_current_sel].bus_type == b2) ? 0 : 1;
if (temp_mo_drives[lv1_current_sel].bus_type == MO_BUS_DISABLED)
temp_mo_drives[lv1_current_sel].type = 0;
temp_mo_drives[lv1_current_sel].bus_type = b2;
mo_recalc_location_controls(hdlg, assign);
mo_track(lv1_current_sel);
win_settings_mo_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_COMBO_MO_ID:
mo_untrack(lv1_current_sel);
temp_mo_drives[lv1_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_MO_ID);
mo_track(lv1_current_sel);
win_settings_mo_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_COMBO_MO_CHANNEL_IDE:
mo_untrack(lv1_current_sel);
temp_mo_drives[lv1_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_MO_CHANNEL_IDE);
mo_track(lv1_current_sel);
win_settings_mo_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_COMBO_MO_TYPE:
temp_mo_drives[lv1_current_sel].type = settings_get_cur_sel(hdlg, IDC_COMBO_MO_TYPE);
win_settings_mo_drives_update_item(hdlg, lv1_current_sel);
break;
case IDC_COMBO_ZIP_BUS:
b = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_BUS);
switch (b) {
case 0:
b2 = ZIP_BUS_DISABLED;
break;
case 1:
b2 = ZIP_BUS_ATAPI;
break;
case 2:
b2 = ZIP_BUS_SCSI;
break;
}
if (b2 == temp_zip_drives[lv2_current_sel].bus_type)
break;
zip_untrack(lv2_current_sel);
assign = (temp_zip_drives[lv2_current_sel].bus_type == b2) ? 0 : 1;
temp_zip_drives[lv2_current_sel].bus_type = b2;
zip_recalc_location_controls(hdlg, assign);
zip_track(lv2_current_sel);
win_settings_zip_drives_update_item(hdlg, lv2_current_sel);
break;
case IDC_COMBO_ZIP_ID:
zip_untrack(lv2_current_sel);
temp_zip_drives[lv2_current_sel].scsi_device_id = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_ID);
zip_track(lv2_current_sel);
win_settings_zip_drives_update_item(hdlg, lv2_current_sel);
break;
case IDC_COMBO_ZIP_CHANNEL_IDE:
zip_untrack(lv2_current_sel);
temp_zip_drives[lv2_current_sel].ide_channel = settings_get_cur_sel(hdlg, IDC_COMBO_ZIP_CHANNEL_IDE);
zip_track(lv2_current_sel);
win_settings_zip_drives_update_item(hdlg, lv2_current_sel);
break;
case IDC_CHECK250:
temp_zip_drives[lv2_current_sel].is_250 = settings_get_check(hdlg, IDC_CHECK250);
win_settings_zip_drives_update_item(hdlg, lv2_current_sel);
break;
}
ignore_change = 0;
case WM_DPICHANGED_AFTERPARENT:
win_settings_mo_drives_resize_columns(hdlg);
image_list_init(hdlg, IDC_LIST_MO_DRIVES, (const uint8_t *) mo_icons);
win_settings_zip_drives_resize_columns(hdlg);
image_list_init(hdlg, IDC_LIST_ZIP_DRIVES, (const uint8_t *) zip_icons);
break;
default:
return FALSE;
}
return FALSE;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int c;
int d;
int e;
LPTSTR lptsTemp;
char *stransi;
const device_t *dev;
switch (message) {
case WM_INITDIALOG:
lptsTemp = (LPTSTR) malloc(512 * sizeof(WCHAR));
stransi = (char *) malloc(512);
/* Populate the ISA RTC card dropdown. */
e = 0;
settings_reset_content(hdlg, IDC_COMBO_ISARTC);
for (d = 0;; d++) {
generate_device_name(isartc_get_device(d), isartc_get_internal_name(d), 0);
if (!device_name[0])
break;
dev = isartc_get_device(d);
if (device_is_valid(dev, temp_machine)) {
if (d == 0) {
settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2104));
settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0);
} else
settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name);
settings_list_to_device[1][e] = d;
if (d == temp_isartc)
settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e);
e++;
}
}
settings_enable_window(hdlg, IDC_COMBO_ISARTC, machine_has_bus(temp_machine, MACHINE_BUS_ISA));
settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, ((temp_isartc != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA)));
/* Populate the ISA memory card dropdowns. */
for (c = 0; c < ISAMEM_MAX; c++) {
e = 0;
settings_reset_content(hdlg, IDC_COMBO_ISAMEM_1 + c);
for (d = 0;; d++) {
generate_device_name(isamem_get_device(d), (char *) isamem_get_internal_name(d), 0);
if (!device_name[0])
break;
dev = isamem_get_device(d);
if (device_is_valid(dev, temp_machine)) {
if (d == 0) {
settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2104));
settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0);
} else
settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name);
settings_list_to_device[0][e] = d;
if (d == temp_isamem[c])
settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, e);
e++;
}
}
settings_enable_window(hdlg, IDC_COMBO_ISAMEM_1 + c, machine_has_bus(temp_machine, MACHINE_BUS_ISA));
settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, ((temp_isamem[c] != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA)));
}
settings_enable_window(hdlg, IDC_CHECK_BUGGER, machine_has_bus(temp_machine, MACHINE_BUS_ISA));
settings_set_check(hdlg, IDC_CHECK_BUGGER, (temp_bugger && machine_has_bus(temp_machine, MACHINE_BUS_ISA)));
settings_set_check(hdlg, IDC_CHECK_POSTCARD, temp_postcard);
free(stransi);
free(lptsTemp);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_CONFIGURE_ISARTC:
temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *) isartc_get_device(temp_isartc));
break;
case IDC_COMBO_ISARTC:
temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)];
settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, temp_isartc != 0);
break;
case IDC_COMBO_ISAMEM_1:
case IDC_COMBO_ISAMEM_2:
case IDC_COMBO_ISAMEM_3:
case IDC_COMBO_ISAMEM_4:
c = LOWORD(wParam) - IDC_COMBO_ISAMEM_1;
temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, LOWORD(wParam))];
settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0);
break;
case IDC_CONFIGURE_ISAMEM_1:
case IDC_CONFIGURE_ISAMEM_2:
case IDC_CONFIGURE_ISAMEM_3:
case IDC_CONFIGURE_ISAMEM_4:
c = LOWORD(wParam) - IDC_CONFIGURE_ISAMEM_1;
temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *) isamem_get_device(temp_isamem[c]), c + 1);
break;
}
return FALSE;
case WM_SAVESETTINGS:
temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)];
for (c = 0; c < ISAMEM_MAX; c++) {
temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c)];
}
temp_bugger = settings_get_check(hdlg, IDC_CHECK_BUGGER);
temp_postcard = settings_get_check(hdlg, IDC_CHECK_POSTCARD);
default:
return FALSE;
}
return FALSE;
}
void
win_settings_show_child(HWND hwndParent, DWORD child_id)
{
if (child_id == displayed_category)
return;
else
displayed_category = child_id;
SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0);
DestroyWindow(hwndChildDialog);
switch (child_id) {
case SETTINGS_PAGE_MACHINE:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc);
break;
case SETTINGS_PAGE_VIDEO:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_VIDEO, hwndParent, win_settings_video_proc);
break;
case SETTINGS_PAGE_INPUT:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_INPUT, hwndParent, win_settings_input_proc);
break;
case SETTINGS_PAGE_SOUND:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_SOUND, hwndParent, win_settings_sound_proc);
break;
case SETTINGS_PAGE_NETWORK:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_NETWORK, hwndParent, win_settings_network_proc);
break;
case SETTINGS_PAGE_PORTS:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_PORTS, hwndParent, win_settings_ports_proc);
break;
case SETTINGS_PAGE_STORAGE:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_STORAGE, hwndParent, win_settings_storage_proc);
break;
case SETTINGS_PAGE_HARD_DISKS:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc);
break;
case SETTINGS_PAGE_FLOPPY_AND_CDROM_DRIVES:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_FLOPPY_AND_CDROM_DRIVES, hwndParent, win_settings_floppy_and_cdrom_drives_proc);
break;
case SETTINGS_PAGE_OTHER_REMOVABLE_DEVICES:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_OTHER_REMOVABLE_DEVICES, hwndParent, win_settings_other_removable_devices_proc);
break;
case SETTINGS_PAGE_PERIPHERALS:
hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc);
break;
default:
fatal("Invalid child dialog ID\n");
return;
}
ShowWindow(hwndChildDialog, SW_SHOWNORMAL);
}
static BOOL
win_settings_main_insert_categories(HWND hwndList)
{
LVITEM lvI;
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvI.stateMask = lvI.iSubItem = lvI.state = 0;
for (uint8_t i = 0; i < 11; i++) {
lvI.pszText = plat_get_string(IDS_2065 + i);
lvI.iItem = i;
lvI.iImage = i;
if (ListView_InsertItem(hwndList, &lvI) == -1)
return FALSE;
}
return TRUE;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_confirm(HWND hdlg)
{
int i;
SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0);
if (win_settings_changed()) {
if (confirm_save && !settings_only)
i = settings_msgbox_ex(MBX_QUESTION_OK | MBX_WARNING | MBX_DONTASK, (wchar_t *) IDS_2122, (wchar_t *) IDS_2123, (wchar_t *) IDS_2124, NULL, NULL);
else
i = 0;
if (i == 10) {
confirm_save = 0;
i = 0;
}
if (i == 0)
win_settings_save();
else
return FALSE;
}
DestroyWindow(hwndChildDialog);
EndDialog(hdlg, 0);
win_notify_dlg_closed();
return TRUE;
}
static void
win_settings_categories_resize_columns(HWND hdlg)
{
HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST);
RECT r;
GetWindowRect(hwndList, &r);
ListView_SetColumnWidth(hwndList, 0, (r.right - r.left) + 1 - 5);
}
static BOOL
win_settings_categories_init_columns(HWND hdlg)
{
LVCOLUMN lvc;
int iCol = 0;
HWND hwndList = GetDlgItem(hdlg, IDC_SETTINGSCATLIST);
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.iSubItem = 0;
lvc.pszText = plat_get_string(2048);
lvc.cx = 171;
lvc.fmt = LVCFMT_LEFT;
if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1)
return FALSE;
win_settings_categories_resize_columns(hdlg);
return TRUE;
}
#if defined(__amd64__) || defined(__aarch64__)
static LRESULT CALLBACK
#else
static BOOL CALLBACK
#endif
win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND h = NULL;
int category;
int j = 0;
const uint8_t cat_icons[12] = { 240, 241, 242, 243, 96, 244, 252, 80, 246, 247, 245, 0 };
hwndParentDialog = hdlg;
switch (message) {
case WM_INITDIALOG:
dpi = win_get_dpi(hdlg);
win_settings_init();
displayed_category = -1;
h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST);
win_settings_categories_init_columns(hdlg);
image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons);
win_settings_main_insert_categories(h);
settings_listview_select(hdlg, IDC_SETTINGSCATLIST, first_cat);
settings_listview_enable_styles(hdlg, IDC_SETTINGSCATLIST);
return TRUE;
case WM_NOTIFY:
if ((((LPNMHDR) lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR) lParam)->idFrom == IDC_SETTINGSCATLIST)) {
category = -1;
for (uint8_t i = 0; i < 11; i++) {
h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST);
j = ListView_GetItemState(h, i, LVIS_SELECTED);
if (j)
category = i;
}
if (category != -1)
win_settings_show_child(hdlg, category);
}
break;
case WM_CLOSE:
DestroyWindow(hwndChildDialog);
EndDialog(hdlg, 0);
win_notify_dlg_closed();
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
return win_settings_confirm(hdlg);
case IDCANCEL:
DestroyWindow(hwndChildDialog);
EndDialog(hdlg, 0);
win_notify_dlg_closed();
return TRUE;
}
break;
case WM_DPICHANGED:
dpi = HIWORD(wParam);
win_settings_categories_resize_columns(hdlg);
image_list_init(hdlg, IDC_SETTINGSCATLIST, (const uint8_t *) cat_icons);
break;
default:
return FALSE;
}
return FALSE;
}
void
win_settings_open_ex(HWND hwnd, int category)
{
win_notify_dlg_open();
first_cat = category;
DialogBox(hinstance, (LPCWSTR) DLG_CONFIG, hwnd, win_settings_main_proc);
}
void
win_settings_open(HWND hwnd)
{
win_settings_open_ex(hwnd, SETTINGS_PAGE_MACHINE);
}