Files
86Box/src/config.c

3358 lines
119 KiB
C
Raw Normal View History

/*
2022-07-21 21:44:55 -04:00
* 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.
*
* Configuration file handler.
*
2023-01-08 14:25:18 +01:00
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Overdoze,
* David Hrdlička, <hrdlickadavid@outlook.com>
2024-11-30 18:48:22 -05:00
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2008-2019 Sarah Walker.
* Copyright 2016-2019 Miran Grca.
* Copyright 2017-2019 Fred N. van Kempen.
2023-01-08 14:25:18 +01:00
* Copyright 2018-2019 David Hrdlička.
2023-02-14 20:37:58 -05:00
* Copyright 2021 Andreas J. Reichel.
2024-11-30 18:48:22 -05:00
* Copyright 2021-2025 Jasmine Iwanek.
*
2022-07-21 21:44:55 -04:00
* NOTE: Forcing config files to be in Unicode encoding breaks
* it on Windows XP, and possibly also Vista. Use the
* -DANSI_CFG for use on these systems.
*/
#include <inttypes.h>
#ifdef ENABLE_CONFIG_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
2020-02-29 19:12:23 +01:00
#include "cpu.h"
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/cassette.h>
2021-07-29 20:34:55 +02:00
#include <86box/cartridge.h>
#include <86box/nvr.h>
2022-09-10 13:32:46 +02:00
#include <86box/ini.h>
#include <86box/config.h>
#include <86box/isamem.h>
2025-05-04 21:44:53 -04:00
#include <86box/isarom.h>
#include <86box/isartc.h>
#include <86box/lpt.h>
2022-07-28 16:50:49 -04:00
#include <86box/serial.h>
#include <86box/hdd.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
2020-06-16 16:41:35 +02:00
#include <86box/fdc_ext.h>
#include <86box/gameport.h>
2025-07-27 15:23:43 +02:00
#include <86box/keyboard.h>
2023-02-14 20:37:58 -05:00
#include <86box/serial_passthrough.h>
#include <86box/machine.h>
#include <86box/mouse.h>
#include <86box/thread.h>
#include <86box/network.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/cdrom_interface.h>
#include <86box/rdisk.h>
#include <86box/mo.h>
#include <86box/sound.h>
#include <86box/midi.h>
#include <86box/snd_mpu401.h>
#include <86box/video.h>
2022-04-19 23:06:39 +02:00
#include <86box/path.h>
#include <86box/plat.h>
#include <86box/plat_dir.h>
#include <86box/ui.h>
#include <86box/snd_opl.h>
#include <86box/version.h>
#ifndef USE_SDL_UI
2025-03-09 01:39:07 +06:00
/* Deliberate to not make the 86box.h header kitchen-sink. */
#include <86box/qt-glsl.h>
extern char gl3_shader_file[MAX_USER_SHADERS][512];
#endif
2025-03-09 01:39:07 +06:00
2023-05-11 03:02:36 -04:00
static int cx;
static int cy;
static int cw;
static int ch;
2022-09-10 13:32:46 +02:00
static ini_t config;
#ifdef ENABLE_CONFIG_LOG
int config_do_log = ENABLE_CONFIG_LOG;
static void
config_log(const char *fmt, ...)
{
va_list ap;
if (config_do_log) {
2022-07-21 21:44:55 -04:00
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
2022-07-21 21:44:55 -04:00
# define config_log(fmt, ...)
#endif
2025-04-19 19:44:47 -07:00
/* Load "General" section. */
static void
load_general(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "General");
2022-09-18 17:11:43 -04:00
char temp[512];
char *p;
2022-09-10 13:32:46 +02:00
vid_resize = ini_section_get_int(cat, "vid_resize", 0);
if (vid_resize & ~3)
2022-07-21 21:44:55 -04:00
vid_resize &= 3;
memset(temp, '\0', sizeof(temp));
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "vid_renderer", "default");
vid_api = plat_vidapi(p);
if (!strcmp(p, "default"))
ini_section_delete_var(cat, "vid_api");
video_fullscreen_scale = ini_section_get_int(cat, "video_fullscreen_scale", 1);
2022-09-10 13:32:46 +02:00
video_filter_method = ini_section_get_int(cat, "video_filter_method", 1);
inhibit_multimedia_keys = ini_section_get_int(cat, "inhibit_multimedia_keys", 0);
2022-09-10 13:32:46 +02:00
force_43 = !!ini_section_get_int(cat, "force_43", 0);
scale = ini_section_get_int(cat, "scale", 1);
if (scale > 9)
scale = 9;
2022-09-10 13:32:46 +02:00
dpi_scale = ini_section_get_int(cat, "dpi_scale", 1);
2022-09-10 13:32:46 +02:00
enable_overscan = !!ini_section_get_int(cat, "enable_overscan", 0);
vid_cga_contrast = !!ini_section_get_int(cat, "vid_cga_contrast", 0);
video_grayscale = ini_section_get_int(cat, "video_grayscale", 0);
video_graytype = ini_section_get_int(cat, "video_graytype", 0);
force_10ms = !!ini_section_get_int(cat, "force_10ms", 0);
2022-09-10 13:32:46 +02:00
rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0);
update_icons = ini_section_get_int(cat, "update_icons", 1);
2022-09-10 13:32:46 +02:00
window_remember = ini_section_get_int(cat, "window_remember", 0);
if (!window_remember && !(vid_resize & 2))
2022-07-21 21:44:55 -04:00
window_w = window_h = window_x = window_y = 0;
if (vid_resize & 2) {
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "window_fixed_res", NULL);
2022-07-21 21:44:55 -04:00
if (p == NULL)
p = "120x120";
sscanf(p, "%ix%i", &fixed_size_x, &fixed_size_y);
if (fixed_size_x < 120)
fixed_size_x = 120;
if (fixed_size_x > 2048)
fixed_size_x = 2048;
if (fixed_size_y < 120)
fixed_size_y = 120;
if (fixed_size_y > 2048)
fixed_size_y = 2048;
} else {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "window_fixed_res");
2022-07-21 21:44:55 -04:00
fixed_size_x = fixed_size_y = 120;
}
2022-09-10 13:32:46 +02:00
sound_gain = ini_section_get_int(cat, "sound_gain", 0);
2022-09-10 13:32:46 +02:00
kbd_req_capture = ini_section_get_int(cat, "kbd_req_capture", 0);
hide_status_bar = ini_section_get_int(cat, "hide_status_bar", 0);
hide_tool_bar = ini_section_get_int(cat, "hide_tool_bar", 0);
2025-03-07 00:36:09 +06:00
sound_muted = ini_section_get_int(cat, "sound_muted", 0);
2022-09-10 13:32:46 +02:00
confirm_reset = ini_section_get_int(cat, "confirm_reset", 1);
confirm_exit = ini_section_get_int(cat, "confirm_exit", 1);
confirm_save = ini_section_get_int(cat, "confirm_save", 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "language", NULL);
2022-07-18 02:17:16 +02:00
if (p != NULL)
2022-07-21 21:44:55 -04:00
lang_id = plat_language_code(p);
else
lang_id = plat_language_code(DEFAULT_LANGUAGE);
2022-09-10 13:32:46 +02:00
mouse_sensitivity = ini_section_get_double(cat, "mouse_sensitivity", 1.0);
if (mouse_sensitivity < 0.1)
mouse_sensitivity = 0.1;
2022-06-01 15:31:58 +06:00
else if (mouse_sensitivity > 2.0)
2022-07-21 21:44:55 -04:00
mouse_sensitivity = 2.0;
2022-09-10 13:32:46 +02:00
enable_discord = !!ini_section_get_int(cat, "enable_discord", 0);
2022-09-10 13:32:46 +02:00
open_dir_usr_path = ini_section_get_int(cat, "open_dir_usr_path", 0);
2022-09-10 13:32:46 +02:00
video_framerate = ini_section_get_int(cat, "video_gl_framerate", -1);
video_vsync = ini_section_get_int(cat, "video_gl_vsync", 0);
2022-09-10 13:32:46 +02:00
window_remember = ini_section_get_int(cat, "window_remember", 0);
if (window_remember) {
2022-09-18 17:11:43 -04:00
p = ini_section_get_string(cat, "window_coordinates", NULL);
if (p == NULL)
p = "640, 480, 0, 0";
2022-09-18 17:11:43 -04:00
sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy);
} else {
2022-09-18 17:11:43 -04:00
cw = ch = cx = cy = 0;
ini_section_delete_var(cat, "window_coordinates");
}
do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0);
p = ini_section_get_string(cat, "uuid", NULL);
if (p != NULL)
strncpy(uuid, p, sizeof(uuid) - 1);
else
strncpy(uuid, "", sizeof(uuid) - 1);
}
/* Load monitor section. */
static void
load_monitor(int monitor_index)
{
ini_section_t cat;
char name[512];
char temp[512];
const char * p = NULL;
monitor_settings_t *ms = &monitor_settings[monitor_index];
2022-09-10 13:32:46 +02:00
sprintf(name, "Monitor #%i", monitor_index + 1);
sprintf(temp, "%i, %i, %i, %i", cx, cy, cw, ch);
2022-09-10 13:32:46 +02:00
cat = ini_find_section(config, name);
p = ini_section_get_string(cat, "window_coordinates", temp);
if (window_remember) {
sscanf(p, "%i, %i, %i, %i", &ms->mon_window_x, &ms->mon_window_y,
&ms->mon_window_w, &ms->mon_window_h);
ms->mon_window_maximized = !!ini_section_get_int(cat, "window_maximized", 0);
} else
ms->mon_window_maximized = 0;
}
/* Load "Machine" section. */
static void
load_machine(void)
{
2022-09-18 17:11:43 -04:00
ini_section_t cat = ini_find_section(config, "Machine");
2023-08-21 20:25:33 -04:00
const char *p;
const char *migrate_from = NULL;
2023-05-11 03:02:36 -04:00
int c;
int i;
int j;
2023-05-11 03:02:36 -04:00
int speed;
2022-09-18 17:11:43 -04:00
double multi;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "machine", NULL);
if (p != NULL) {
migrate_from = p;
/* Migrate renamed machines. */
if (!strcmp(p, "tandy"))
machine = machine_get_machine_from_internal_name("tandy1000sx");
else if (!strcmp(p, "430nx"))
machine = machine_get_machine_from_internal_name("586ip");
else if (!strcmp(p, "586mc1"))
machine = machine_get_machine_from_internal_name("586is");
else {
machine = machine_get_machine_from_internal_name(p);
migrate_from = NULL;
}
} else
2022-07-21 21:44:55 -04:00
machine = 0;
if (machine >= machine_count())
2022-07-21 21:44:55 -04:00
machine = machine_count() - 1;
/* Copy NVR files when migrating a machine to a new internal name. */
if (migrate_from) {
char old_fn[256];
strcpy(old_fn, migrate_from);
strcat(old_fn, ".");
c = strlen(old_fn);
char new_fn[256];
strcpy(new_fn, machines[machine].internal_name);
strcat(new_fn, ".");
i = strlen(new_fn);
/* Iterate through NVR files. */
DIR *dirp = opendir(nvr_path("."));
if (dirp) {
struct dirent *entry;
while ((entry = readdir(dirp))) {
/* Check if this file corresponds to the old name. */
if (strncmp(entry->d_name, old_fn, c))
continue;
/* Add extension to the new name. */
strcpy(&new_fn[i], &entry->d_name[c]);
/* Only copy if a file with the new name doesn't already exist. */
FILE *g = nvr_fopen(new_fn, "rb");
if (g == NULL) {
FILE *f = nvr_fopen(entry->d_name, "rb");
g = nvr_fopen(new_fn, "wb");
uint8_t buf[4096];
while ((j = fread(buf, 1, sizeof(buf), f)))
fwrite(buf, 1, j, g);
fclose(f);
}
fclose(g);
}
}
}
2024-04-25 19:14:51 +02:00
cpu_override = ini_section_get_int(cat, "cpu_override", 0);
cpu_override_interpreter = ini_section_get_int(cat, "cpu_override_interpreter", 0);
cpu_f = NULL;
p = ini_section_get_string(cat, "cpu_family", NULL);
2020-11-18 15:18:20 -03:00
if (p) {
/* Migrate CPU family changes. */
if ((!strcmp(machines[machine].internal_name, "deskpro386") ||
!strcmp(machines[machine].internal_name, "deskpro386_05_1988")))
cpu_f = cpu_get_family("i386dx_deskpro386");
else
cpu_f = cpu_get_family(p);
2022-07-21 21:44:55 -04:00
if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */
cpu_f = NULL;
}
2020-11-18 01:09:17 -03:00
if (cpu_f) {
2022-09-10 13:32:46 +02:00
speed = ini_section_get_int(cat, "cpu_speed", 0);
multi = ini_section_get_double(cat, "cpu_multi", 0);
2022-07-21 21:44:55 -04:00
/* Find the configured CPU. */
cpu = 0;
c = 0;
i = 256;
while (cpu_f->cpus[cpu].cpu_type) {
if (cpu_is_eligible(cpu_f, cpu, machine)) {
/* Skip ineligible CPUs. */
if ((cpu_f->cpus[cpu].rspeed == speed) && (cpu_f->cpus[cpu].multi == multi))
/* Exact speed/multiplier match. */
2022-07-21 21:44:55 -04:00
break;
else if ((cpu_f->cpus[cpu].rspeed >= speed) && (i == 256))
/* Closest speed match. */
2022-07-21 21:44:55 -04:00
i = cpu;
c = cpu; /* store fastest eligible CPU */
}
cpu++;
}
if (!cpu_f->cpus[cpu].cpu_type)
/* if no exact match was found, use closest matching faster CPU or fastest eligible CPU. */
2022-07-21 21:44:55 -04:00
cpu = MIN(i, c);
} else {
/* Default, find first eligible family. */
2022-07-21 21:44:55 -04:00
c = 0;
while (!cpu_family_is_eligible(&cpu_families[c], machine)) {
if (cpu_families[c++].package == 0) {
/* End of list. */
fatal("Configuration: No eligible CPU families for the selected machine\n");
2022-07-21 21:44:55 -04:00
return;
}
}
cpu_f = (cpu_family_t *) &cpu_families[c];
/* Find first eligible CPU in that family. */
cpu = 0;
while (!cpu_is_eligible(cpu_f, cpu, machine)) {
if (cpu_f->cpus[cpu++].cpu_type == 0) {
/* End of list. */
2022-07-21 21:44:55 -04:00
cpu = 0;
break;
}
}
}
2020-11-18 15:18:20 -03:00
cpu_s = (CPU *) &cpu_f->cpus[cpu];
2022-09-10 13:32:46 +02:00
cpu_waitstates = ini_section_get_int(cat, "cpu_waitstates", 0);
2023-06-09 23:46:54 -04:00
p = ini_section_get_string(cat, "fpu_type", "none");
2020-11-18 01:09:17 -03:00
fpu_type = fpu_get_type(cpu_f, cpu, p);
2022-09-10 13:32:46 +02:00
mem_size = ini_section_get_int(cat, "mem_size", 64);
2022-02-20 02:26:27 -05:00
if (mem_size > machine_get_max_ram(machine))
mem_size = machine_get_max_ram(machine);
2022-09-10 13:32:46 +02:00
cpu_use_dynarec = !!ini_section_get_int(cat, "cpu_use_dynarec", 0);
fpu_softfloat = !!ini_section_get_int(cat, "fpu_softfloat", 0);
if ((fpu_type != FPU_NONE) && machine_has_flags(machine, MACHINE_SOFTFLOAT_ONLY))
fpu_softfloat = 1;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "time_sync", NULL);
2022-02-20 02:26:27 -05:00
if (p != NULL) {
2022-07-21 21:44:55 -04:00
if (!strcmp(p, "disabled"))
time_sync = TIME_SYNC_DISABLED;
else if (!strcmp(p, "local"))
time_sync = TIME_SYNC_ENABLED;
else if (!strcmp(p, "utc") || !strcmp(p, "gmt"))
time_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC;
else
time_sync = TIME_SYNC_ENABLED;
} else
time_sync = TIME_SYNC_ENABLED;
2022-09-10 13:32:46 +02:00
pit_mode = ini_section_get_int(cat, "pit_mode", -1);
}
/* Load "Video" section. */
static void
load_video(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Video");
2022-09-18 17:11:43 -04:00
char *p;
int free_p = 0;
if (machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "gfxcard");
2023-02-06 04:12:46 -05:00
gfxcard[0] = VID_INTERNAL;
} else {
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "gfxcard", NULL);
2022-07-21 21:44:55 -04:00
if (p == NULL) {
if (machine_has_flags(machine, MACHINE_VIDEO)) {
p = (char *) malloc((strlen("internal") + 1) * sizeof(char));
strcpy(p, "internal");
} else {
p = (char *) malloc((strlen("none") + 1) * sizeof(char));
strcpy(p, "none");
}
free_p = 1;
} else if (!strcmp(p, "c&t_69000")) {
p = (char *) malloc((strlen("chips_69000") + 1) * sizeof(char));
strcpy(p, "chips_69000");
free_p = 1;
2022-07-21 21:44:55 -04:00
}
2023-10-13 23:51:50 +02:00
gfxcard[0] = video_get_video_from_internal_name(p);
if (free_p) {
2022-07-21 21:44:55 -04:00
free(p);
p = NULL;
}
}
if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_8514A)) ||
video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514)
ini_section_delete_var(cat, "8514a");
2022-09-18 17:11:43 -04:00
voodoo_enabled = !!ini_section_get_int(cat, "voodoo", 0);
ibm8514_standalone_enabled = !!ini_section_get_int(cat, "8514a", 0);
ibm8514_active = ibm8514_standalone_enabled;
xga_standalone_enabled = !!ini_section_get_int(cat, "xga", 0);
xga_active = xga_standalone_enabled;
da2_standalone_enabled = !!ini_section_get_int(cat, "da2", 0);
2022-09-18 17:11:43 -04:00
show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1);
2022-09-10 13:32:46 +02:00
video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0);
2022-09-18 17:11:43 -04:00
// TODO
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
p = ini_section_get_string(cat, "gfxcard_2", NULL);
if (!p)
p = "none";
gfxcard[i] = video_get_video_from_internal_name(p);
}
}
/* Load "Input Devices" section. */
static void
load_input_devices(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Input devices");
2022-09-18 17:11:43 -04:00
char temp[512];
char *p;
2025-07-27 15:23:43 +02:00
p = ini_section_get_string(cat, "keyboard_type", NULL);
if (p != NULL)
keyboard_type = keyboard_get_from_internal_name(p);
else if (strstr(machine_get_internal_name(), "pc5086"))
keyboard_type = KEYBOARD_TYPE_PC_XT;
2025-07-27 15:23:43 +02:00
else if (machine_has_bus(machine, MACHINE_BUS_PS2_PORTS)) {
if (machine_has_flags(machine, MACHINE_KEYBOARD_JIS))
keyboard_type = KEYBOARD_TYPE_PS55;
else
keyboard_type = KEYBOARD_TYPE_PS2;
} else if (machine_has_bus(machine, MACHINE_BUS_ISA16) ||
machine_has_bus(machine, MACHINE_BUS_PCI)) {
if (machine_has_flags(machine, MACHINE_KEYBOARD_JIS))
keyboard_type = KEYBOARD_TYPE_AX;
else
keyboard_type = KEYBOARD_TYPE_AT;
} else
keyboard_type = KEYBOARD_TYPE_PC_XT;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "mouse_type", NULL);
if (p != NULL)
2022-07-21 21:44:55 -04:00
mouse_type = mouse_get_from_internal_name(p);
else
mouse_type = 0;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "joystick_type", NULL);
if (p != NULL) {
2023-10-14 00:02:31 +02:00
joystick_type = joystick_get_from_internal_name(p);
2022-07-21 21:44:55 -04:00
if (!joystick_type) {
/* Try to read an integer for backwards compatibility with old configs */
if (!strcmp(p, "0"))
/* Workaround for ini_section_get_int returning 0 on non-integer data */
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("2axis_2button");
else {
2025-01-11 01:31:57 -05:00
int js = ini_section_get_int(cat, "joystick_type", 8);
switch (js) {
2023-08-14 17:20:48 -04:00
case JS_TYPE_2AXIS_4BUTTON:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("2axis_4button");
break;
2023-08-14 17:20:48 -04:00
case JS_TYPE_2AXIS_6BUTTON:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("2axis_6button");
break;
2023-08-14 17:20:48 -04:00
case JS_TYPE_2AXIS_8BUTTON:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("2axis_8button");
break;
2023-08-14 17:20:48 -04:00
case JS_TYPE_4AXIS_4BUTTON:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("4axis_4button");
break;
2023-08-14 17:20:48 -04:00
case JS_TYPE_CH_FLIGHTSTICK_PRO:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("ch_flightstick_pro");
break;
2023-08-14 17:20:48 -04:00
case JS_TYPE_SIDEWINDER_PAD:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("sidewinder_pad");
break;
2023-08-14 17:20:48 -04:00
case JS_TYPE_THRUSTMASTER_FCS:
2022-07-21 21:44:55 -04:00
joystick_type = joystick_get_from_internal_name("thrustmaster_fcs");
break;
default:
2023-08-14 17:20:48 -04:00
joystick_type = JS_TYPE_NONE;
2022-07-21 21:44:55 -04:00
break;
}
}
}
} else
2023-08-14 17:20:48 -04:00
joystick_type = JS_TYPE_NONE;
2022-07-21 21:44:55 -04:00
2025-01-11 01:31:57 -05:00
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) {
sprintf(temp, "joystick_%i_nr", js);
joystick_state[0][js].plat_joystick_nr = ini_section_get_int(cat, temp, 0);
2022-07-21 21:44:55 -04:00
if (joystick_state[0][js].plat_joystick_nr) {
2025-01-11 01:31:57 -05:00
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) {
sprintf(temp, "joystick_%i_axis_%i", js, axis_nr);
joystick_state[0][js].axis_mapping[axis_nr] = ini_section_get_int(cat, temp, axis_nr);
2022-07-21 21:44:55 -04:00
}
2025-01-11 01:31:57 -05:00
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) {
sprintf(temp, "joystick_%i_button_%i", js, button_nr);
joystick_state[0][js].button_mapping[button_nr] = ini_section_get_int(cat, temp, button_nr);
2022-07-21 21:44:55 -04:00
}
2025-01-11 01:31:57 -05:00
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) {
sprintf(temp, "joystick_%i_pov_%i", js, pov_nr);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "0, 0");
joystick_state[0][js].pov_mapping[pov_nr][0] = joystick_state[0][js].pov_mapping[pov_nr][1] = 0;
sscanf(p, "%i, %i", &joystick_state[0][js].pov_mapping[pov_nr][0],
&joystick_state[0][js].pov_mapping[pov_nr][1]);
2022-07-21 21:44:55 -04:00
}
}
}
2023-01-03 15:42:57 +06:00
tablet_tool_type = !!ini_section_get_int(cat, "tablet_tool_type", 1);
}
/* Load "Sound" section. */
static void
load_sound(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Sound");
2022-09-18 17:11:43 -04:00
char temp[512];
char *p;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "sndcard", NULL);
if (p != NULL)
2023-02-01 02:31:07 -05:00
sound_card_current[0] = sound_card_get_from_internal_name(p);
2022-07-21 21:44:55 -04:00
else
2023-02-01 02:31:07 -05:00
sound_card_current[0] = 0;
p = ini_section_get_string(cat, "sndcard2", NULL);
if (p != NULL)
sound_card_current[1] = sound_card_get_from_internal_name(p);
else
sound_card_current[1] = 0;
2023-02-01 02:31:07 -05:00
p = ini_section_get_string(cat, "sndcard3", NULL);
if (p != NULL)
2023-02-01 02:31:07 -05:00
sound_card_current[2] = sound_card_get_from_internal_name(p);
else
sound_card_current[2] = 0;
2023-02-01 02:31:07 -05:00
p = ini_section_get_string(cat, "sndcard4", NULL);
if (p != NULL)
2023-02-01 02:31:07 -05:00
sound_card_current[3] = sound_card_get_from_internal_name(p);
else
sound_card_current[3] = 0;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "midi_device", NULL);
2020-01-01 20:20:16 +01:00
if (p != NULL)
2022-07-21 21:44:55 -04:00
midi_output_device_current = midi_out_device_get_from_internal_name(p);
else
midi_output_device_current = 0;
2020-01-01 20:20:16 +01:00
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "midi_in_device", NULL);
2020-01-01 20:20:16 +01:00
if (p != NULL)
2022-07-21 21:44:55 -04:00
midi_input_device_current = midi_in_device_get_from_internal_name(p);
else
midi_input_device_current = 0;
2020-01-01 20:20:16 +01:00
2022-09-10 13:32:46 +02:00
mpu401_standalone_enable = !!ini_section_get_int(cat, "mpu401_standalone", 0);
/* Backwards compatibility for standalone SSI-2001, CMS and GUS from v3.11 and older. */
2023-04-18 16:16:42 -03:00
const char *legacy_cards[][2] = {
{"ssi2001", "ssi2001"},
{ "gameblaster", "cms" },
{ "gus", "gus" }
};
for (int i = 0, j = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) {
if (ini_section_get_int(cat, legacy_cards[i][0], 0) == 1) {
/* Migrate to the first available sound card slot. */
for (; j < (sizeof(sound_card_current) / sizeof(sound_card_current[0])); j++) {
if (!sound_card_current[j]) {
sound_card_current[j] = sound_card_get_from_internal_name(legacy_cards[i][1]);
break;
}
}
}
}
memset(temp, '\0', sizeof(temp));
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "sound_type", "float");
2021-04-05 23:30:07 +02:00
if (strlen(p) > 511)
fatal("Configuration: Length of sound_type is more than 511\n");
2021-04-05 23:30:07 +02:00
else
2022-10-30 02:00:38 +01:00
strncpy(temp, p, 511);
if (!strcmp(temp, "float") || !strcmp(temp, "1"))
2022-07-21 21:44:55 -04:00
sound_is_float = 1;
else
sound_is_float = 0;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "fm_driver", "nuked");
if (!strcmp(p, "ymfm")) {
fm_driver = FM_DRV_YMFM;
} else {
fm_driver = FM_DRV_NUKED;
}
}
/* Load "Network" section. */
static void
load_network(void)
{
ini_section_t cat = ini_find_section(config, "Network");
char * p;
char temp[512];
uint16_t c = 0;
uint16_t min = 0;
netcard_conf_t *nc = &net_cards_conf[c];
/* Handle legacy configuration which supported only one NIC */
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "net_card", NULL);
if (p != NULL) {
nc->device_num = network_card_get_from_internal_name(p);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "net_type", NULL);
if (p != NULL) {
if (!strcmp(p, "pcap") || !strcmp(p, "1"))
nc->net_type = NET_TYPE_PCAP;
else if (!strcmp(p, "slirp") || !strcmp(p, "2"))
nc->net_type = NET_TYPE_SLIRP;
else if (!strcmp(p, "vde") || !strcmp(p, "3"))
nc->net_type = NET_TYPE_VDE;
else if (!strcmp(p, "tap") || !strcmp(p, "4"))
nc->net_type = NET_TYPE_TAP;
else
nc->net_type = NET_TYPE_NONE;
} else
nc->net_type = NET_TYPE_NONE;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "net_host_device", NULL);
if (p != NULL) {
if (nc->net_type == NET_TYPE_PCAP) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if (network_ndev == 1)
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC));
else if (network_dev_to_id(p) == -1)
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC));
strcpy(nc->host_dev_name, "none");
} else
strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1);
} else
strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1);
} else
strcpy(nc->host_dev_name, "none");
min++;
}
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "net_card");
ini_section_delete_var(cat, "net_type");
ini_section_delete_var(cat, "net_host_device");
for (c = min; c < NET_CARD_MAX; c++) {
nc = &net_cards_conf[c];
sprintf(temp, "net_%02i_card", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL)
nc->device_num = network_card_get_from_internal_name(p);
else
nc->device_num = 0;
sprintf(temp, "net_%02i_net_type", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL) {
if (!strcmp(p, "pcap") || !strcmp(p, "1"))
nc->net_type = NET_TYPE_PCAP;
else if (!strcmp(p, "slirp") || !strcmp(p, "2"))
nc->net_type = NET_TYPE_SLIRP;
else if (!strcmp(p, "vde") || !strcmp(p, "3"))
nc->net_type = NET_TYPE_VDE;
else if (!strcmp(p, "tap") || !strcmp(p, "4"))
nc->net_type = NET_TYPE_TAP;
else
nc->net_type = NET_TYPE_NONE;
} else
nc->net_type = NET_TYPE_NONE;
sprintf(temp, "net_%02i_host_device", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL) {
if (nc->net_type == NET_TYPE_PCAP) {
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
if (network_ndev == 1)
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC));
else if (network_dev_to_id(p) == -1)
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC));
strcpy(nc->host_dev_name, "none");
} else
strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1);
} else
strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1);
} else
strcpy(nc->host_dev_name, "none");
2022-09-18 17:11:43 -04:00
sprintf(temp, "net_%02i_link", c + 1);
nc->link_state = ini_section_get_int(cat, temp,
(NET_LINK_10_HD | NET_LINK_10_FD |
NET_LINK_100_HD | NET_LINK_100_FD |
NET_LINK_1000_HD | NET_LINK_1000_FD));
}
}
/* Load "Ports" section. */
static void
load_ports(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Ports (COM & LPT)");
2022-09-18 17:11:43 -04:00
char *p;
char temp[512];
2023-02-14 20:37:58 -05:00
memset(temp, 0, sizeof(temp));
for (int c = 0; c < (SERIAL_MAX - 1); c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "serial%d_enabled", c + 1);
2022-09-10 13:32:46 +02:00
com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1);
2022-01-31 01:43:12 -05:00
2023-02-14 20:37:58 -05:00
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0);
if (serial_passthrough_enabled[c])
2023-02-28 23:24:58 -05:00
config_log("Serial Port %d: passthrough enabled.\n\n", c + 1);
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
}
2025-01-11 01:31:57 -05:00
for (int c = 0; c < PARALLEL_MAX; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "lpt%d_enabled", c + 1);
2022-09-10 13:32:46 +02:00
lpt_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0);
2022-07-21 21:44:55 -04:00
sprintf(temp, "lpt%d_device", c + 1);
2025-08-02 14:51:28 +02:00
p = ini_section_get_string(cat, temp, "none");
lpt_ports[c].device = lpt_device_get_from_internal_name(p);
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
}
2024-11-30 18:48:22 -05:00
#if 0
// TODO: Load
for (c = 0; c < GAMEPORT_MAX; c++) {
sprintf(temp, "gameport%d_enabled", c + 1);
game_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0);
sprintf(temp, "gameport%d_device", c + 1);
p = ini_section_get_string(cat, temp, "none");
game_ports[c].device = gameport_get_from_internal_name(p);
}
for (uint8_t c = 0; c < GAMEPORT_MAX; c++) {
sprintf(temp, "gameport%d_type", c);
p = ini_section_get_string(cat, temp, "none");
gameport_type[c] = gameport_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
#endif
}
static int
load_image_file(char *dest, char *p, uint8_t *ui_wp)
{
char *prefix = "";
int ret = 0;
if (strstr(p, "wp://") == p) {
p += 5;
prefix = "wp://";
if (ui_wp != NULL)
*ui_wp = 1;
} else if ((ui_wp != NULL) && *ui_wp)
prefix = "wp://";
if (path_abs(p)) {
2025-07-29 15:01:12 +02:00
if ((strlen(prefix) + strlen(p)) > (MAX_IMAGE_PATH_LEN - 1))
ret = 1;
else
snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s", prefix, p);
2025-07-29 15:01:12 +02:00
} else {
if ((strlen(prefix) + strlen(usr_path) + strlen(path_get_slash(usr_path)) + strlen(p)) > (MAX_IMAGE_PATH_LEN - 1))
ret = 1;
else
snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, usr_path, path_get_slash(usr_path), p);
}
path_normalize(dest);
return ret;
}
/* Load "Storage Controllers" section. */
static void
load_storage_controllers(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Storage controllers");
ini_section_t migration_cat;
2023-05-11 03:02:36 -04:00
char *p;
char temp[512];
int min = 0;
2025-01-11 01:31:57 -05:00
for (int c = min; c < SCSI_CARD_MAX; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "scsicard_%d", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
2022-07-21 21:44:55 -04:00
if (p != NULL)
scsi_card_current[c] = scsi_card_get_from_internal_name(p);
else
scsi_card_current[c] = 0;
}
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "fdc", NULL);
2024-07-08 14:29:27 -04:00
#if 1
if (p != NULL)
fdc_current[0] = fdc_card_get_from_internal_name(p);
2022-07-21 21:44:55 -04:00
else
fdc_current[0] = FDC_INTERNAL;
2024-06-29 22:16:04 -04:00
#else
int free_p = 0;
2024-06-29 22:16:04 -04:00
if (p == NULL) {
if (machine_has_flags(machine, MACHINE_FDC)) {
p = (char *) malloc((strlen("internal") + 1) * sizeof(char));
strcpy(p, "internal");
} else {
p = (char *) malloc((strlen("none") + 1) * sizeof(char));
strcpy(p, "none");
}
free_p = 1;
}
fdc_current[0] = fdc_card_get_from_internal_name(p);
2024-06-29 22:16:04 -04:00
if (free_p) {
free(p);
p = NULL;
free_p = 0;
}
#endif
for (int c = min; c < HDC_MAX; c++) {
sprintf(temp, "hdc_%d", c + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL)
hdc_current[c] = hdc_get_from_internal_name(p);
else
hdc_current[c] = 0;
}
/* Backwards compatibility for single HDC and standalone tertiary/quaternary IDE from v4.2 and older. */
const char *legacy_cards[] = { NULL, "ide_ter", "ide_qua" };
p = ini_section_get_string(cat, "hdc", NULL);
for (int i = !(p || machine_has_flags(machine, MACHINE_HDC)), j = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) {
if (!legacy_cards[i] || (ini_section_get_int(cat, legacy_cards[i], 0) == 1)) {
/* Migrate to the first available HDC slot. */
for (; j < (sizeof(hdc_current) / sizeof(hdc_current[0])); j++) {
if (!hdc_current[j]) {
if (!legacy_cards[i]) {
if (!p) {
hdc_current[j] = hdc_get_from_internal_name("internal");
} else if (!strcmp(p, "xtide_plus")) {
hdc_current[j] = hdc_get_from_internal_name("xtide");
sprintf(temp, "PC/XT XTIDE #%i", j + 1);
migration_cat = ini_find_or_create_section(config, temp);
ini_section_set_string(migration_cat, "bios", "xt_plus");
} else if (!strcmp(p, "xtide_at_386")) {
hdc_current[j] = hdc_get_from_internal_name("xtide_at");
sprintf(temp, "PC/AT XTIDE #%i", j + 1);
migration_cat = ini_find_or_create_section(config, temp);
ini_section_set_string(migration_cat, "bios", "at_386");
} else {
hdc_current[j] = hdc_get_from_internal_name(p);
}
} else {
hdc_current[j] = hdc_get_from_internal_name(legacy_cards[i]);
}
break;
}
}
2022-07-21 21:44:55 -04:00
}
2020-01-15 03:04:59 +01:00
}
ini_section_delete_var(cat, "hdc");
2020-01-15 03:04:59 +01:00
p = ini_section_get_string(cat, "cdrom_interface", NULL);
if (p != NULL)
cdrom_interface_current = cdrom_interface_get_from_internal_name(p);
if (machine_has_bus(machine, MACHINE_BUS_CASSETTE))
cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0);
else
cassette_enable = 0;
2024-08-27 03:29:37 +02:00
cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0);
ini_section_delete_var(cat, "cassette_writeprot");
p = ini_section_get_string(cat, "cassette_file", "");
2024-08-27 03:29:37 +02:00
if (!strcmp(p, usr_path))
p[0] = 0x00;
if (p[0] != 0x00) {
if (load_image_file(cassette_fname, p, (uint8_t *) &cassette_ui_writeprot))
fatal("Configuration: Length of cassette_file is more than 511\n");
2024-08-27 03:29:37 +02:00
}
p = ini_section_get_string(cat, "cassette_mode", "load");
2021-07-28 00:58:19 +02:00
if (strlen(p) > 511)
fatal("Configuration: Length of cassette_mode is more than 511\n");
2021-07-28 00:58:19 +02:00
else
2022-10-30 02:00:38 +01:00
strncpy(cassette_mode, p, 511);
2024-08-27 03:29:37 +02:00
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cassette_image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "cassette_image_history_%02i", i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (load_image_file(cassette_image_history[i], p, NULL))
fatal("Configuration: Length of cassette_image_history_%02i is more "
"than %i\n", i + 1, MAX_IMAGE_PATH_LEN - 1);
2024-08-27 03:29:37 +02:00
}
}
2022-09-10 13:32:46 +02:00
cassette_pos = ini_section_get_int(cat, "cassette_position", 0);
if (!cassette_pos)
ini_section_delete_var(cat, "cassette_position");
2022-09-10 13:32:46 +02:00
cassette_srate = ini_section_get_int(cat, "cassette_srate", 44100);
if (cassette_srate == 44100)
ini_section_delete_var(cat, "cassette_srate");
2022-09-10 13:32:46 +02:00
cassette_append = !!ini_section_get_int(cat, "cassette_append", 0);
if (!cassette_append)
ini_section_delete_var(cat, "cassette_append");
2022-09-10 13:32:46 +02:00
cassette_pcm = ini_section_get_int(cat, "cassette_pcm", 0);
if (!cassette_pcm)
ini_section_delete_var(cat, "cassette_pcm");
if (!cassette_enable) {
ini_section_delete_var(cat, "cassette_file");
ini_section_delete_var(cat, "cassette_mode");
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cassette_image_history_%02i", i + 1);
ini_section_delete_var(cat, temp);
}
ini_section_delete_var(cat, "cassette_position");
ini_section_delete_var(cat, "cassette_srate");
ini_section_delete_var(cat, "cassette_append");
ini_section_delete_var(cat, "cassette_pcm");
ini_section_delete_var(cat, "cassette_ui_writeprot");
}
2021-07-29 20:34:55 +02:00
2025-01-11 01:31:57 -05:00
for (int c = 0; c < 2; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "cartridge_%02i_fn", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "");
2021-07-29 20:34:55 +02:00
2023-08-22 19:06:57 +02:00
if (!strcmp(p, usr_path))
2023-08-22 19:16:18 +02:00
p[0] = 0x00;
2023-08-22 19:06:57 +02:00
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("Configuration: Length of cartridge_%02i_fn is more than 511\n",
c + 1);
2023-08-22 19:06:57 +02:00
else
strncpy(cart_fns[c], p, 511);
} else
path_append_filename(cart_fns[c], usr_path, p);
path_normalize(cart_fns[c]);
}
2024-08-27 03:29:37 +02:00
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cart_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
2024-08-27 05:09:35 +02:00
sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
2024-08-27 03:29:37 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("Configuration: Length of cartridge_%02i_image_history_%02i "
"is more than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
2024-08-27 03:29:37 +02:00
else
2024-12-13 06:06:49 +01:00
snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p);
2024-08-27 03:29:37 +02:00
} else
2024-12-13 06:06:49 +01:00
snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path,
2024-08-27 03:29:37 +02:00
path_get_slash(usr_path), p);
path_normalize(cart_image_history[c][i]);
}
}
2021-07-29 20:34:55 +02:00
}
}
/* Load "Hard Disks" section. */
static void
load_hard_disks(void)
{
2022-09-18 17:11:43 -04:00
ini_section_t cat = ini_find_section(config, "Hard disks");
2023-05-11 03:02:36 -04:00
char temp[512];
char tmp2[512];
2022-09-18 17:11:43 -04:00
char s[512];
char *p;
2023-05-11 03:02:36 -04:00
uint32_t max_spt;
uint32_t max_hpc;
uint32_t max_tracks;
uint32_t board = 0;
uint32_t dev = 0;
memset(temp, '\0', sizeof(temp));
2023-05-11 03:02:36 -04:00
for (uint8_t c = 0; c < HDD_NUM; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_parameters", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "0, 0, 0, 0, none");
2022-07-21 21:44:55 -04:00
sscanf(p, "%u, %u, %u, %i, %s",
&hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, (int *) &hdd[c].wp, s);
hdd[c].bus_type = hdd_string_to_bus(s, 0);
switch (hdd[c].bus_type) {
2022-07-21 21:44:55 -04:00
default:
2023-06-28 13:46:28 -04:00
case HDD_BUS_DISABLED:
2022-07-21 21:44:55 -04:00
max_spt = max_hpc = max_tracks = 0;
break;
case HDD_BUS_MFM:
max_spt = 26; /* 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;
max_hpc = 16;
max_tracks = 266305;
break;
case HDD_BUS_IDE:
max_spt = 255;
max_hpc = 255;
2022-07-21 21:44:55 -04:00
max_tracks = 266305;
break;
case HDD_BUS_SCSI:
case HDD_BUS_ATAPI:
max_spt = 255;
2022-07-21 21:44:55 -04:00
max_hpc = 255;
max_tracks = 266305;
break;
}
if (hdd[c].spt > max_spt)
hdd[c].spt = max_spt;
if (hdd[c].hpc > max_hpc)
hdd[c].hpc = max_hpc;
if (hdd[c].tracks > max_tracks)
hdd[c].tracks = max_tracks;
sprintf(temp, "hdd_%02i_speed", c + 1);
switch (hdd[c].bus_type) {
2022-07-21 21:44:55 -04:00
case HDD_BUS_IDE:
2022-07-29 00:47:52 +02:00
case HDD_BUS_ESDI:
case HDD_BUS_ATAPI:
case HDD_BUS_SCSI:
2022-07-21 21:44:55 -04:00
sprintf(tmp2, "1997_5400rpm");
break;
default:
sprintf(tmp2, "ramdisk");
break;
}
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
hdd[c].speed_preset = hdd_preset_get_from_internal_name(p);
/* MFM/RLL */
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
if (hdd[c].bus_type == HDD_BUS_MFM)
2022-09-10 13:32:46 +02:00
hdd[c].mfm_channel = !!ini_section_get_int(cat, temp, c & 1);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
/* XTA */
sprintf(temp, "hdd_%02i_xta_channel", c + 1);
if (hdd[c].bus_type == HDD_BUS_XTA)
2022-09-10 13:32:46 +02:00
hdd[c].xta_channel = !!ini_section_get_int(cat, temp, c & 1);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
/* ESDI */
sprintf(temp, "hdd_%02i_esdi_channel", c + 1);
if (hdd[c].bus_type == HDD_BUS_ESDI)
2022-09-10 13:32:46 +02:00
hdd[c].esdi_channel = !!ini_section_get_int(cat, temp, c & 1);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
/* IDE */
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if ((hdd[c].bus_type == HDD_BUS_IDE) || (hdd[c].bus_type == HDD_BUS_ATAPI)) {
2022-07-21 21:44:55 -04:00
sprintf(tmp2, "%01u:%01u", c >> 1, c & 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
hdd[c].ide_channel = (board << 1) + dev;
if (hdd[c].ide_channel > 7)
hdd[c].ide_channel = 7;
} else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
/* SCSI */
if (hdd[c].bus_type == HDD_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
sprintf(temp, "hdd_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
hdd[c].scsi_id = ini_section_get_int(cat, temp, c + 2);
2022-07-21 21:44:55 -04:00
if (hdd[c].scsi_id > 15)
hdd[c].scsi_id = 15;
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
hdd[c].scsi_id = (board << 4) + dev;
}
} else {
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "hdd_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn));
sprintf(temp, "hdd_%02i_fn", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "");
2022-07-21 21:44:55 -04:00
/*
* NOTE:
* When loading differencing VHDs, the absolute path is required.
* So we should not convert absolute paths to relative. -sards
2022-07-21 21:44:55 -04:00
*/
2023-08-22 19:06:57 +02:00
if (!strcmp(p, usr_path))
2023-08-22 19:16:18 +02:00
p[0] = 0x00;
2023-08-22 19:06:57 +02:00
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("Configuration: Length of hdd_%02i_fn is more "
"than 511\n", c + 1);
2023-08-22 19:06:57 +02:00
else
strncpy(hdd[c].fn, p, 511);
} else
path_append_filename(hdd[c].fn, usr_path, p);
path_normalize(hdd[c].fn);
}
sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1);
hdd[c].vhd_blocksize = ini_section_get_int(cat, temp, 0);
sprintf(temp, "hdd_%02i_vhd_parent", c + 1);
p = ini_section_get_string(cat, temp, "");
strncpy(hdd[c].vhd_parent, p, sizeof(hdd[c].vhd_parent) - 1);
2022-07-21 21:44:55 -04:00
/* If disk is empty or invalid, mark it for deletion. */
if (!hdd_is_valid(c)) {
sprintf(temp, "hdd_%02i_parameters", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_xta_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_esdi_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_fn", c + 1);
ini_section_delete_var(cat, temp);
}
}
}
/* Load "Floppy and CD-ROM Drives" section. */
static void
load_floppy_and_cdrom_drives(void)
{
2022-09-18 17:11:43 -04:00
ini_section_t cat = ini_find_section(config, "Floppy and CD-ROM drives");
2023-05-11 03:02:36 -04:00
char temp[512];
char tmp2[512];
char *p;
2022-09-18 17:11:43 -04:00
char s[512];
2023-05-11 03:02:36 -04:00
unsigned int board = 0;
unsigned int dev = 0;
int c;
int d;
int count = cdrom_get_type_count();
memset(temp, 0x00, sizeof(temp));
2022-07-21 21:44:55 -04:00
for (c = 0; c < FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, (c < 2) ? "525_2dd" : "none");
if (!strcmp(p, "525_2hd_ps2"))
d = fdd_get_from_internal_name("525_2hd");
else if (!strcmp(p, "35_2hd_ps2"))
d = fdd_get_from_internal_name("35_2hd");
else
d = fdd_get_from_internal_name(p);
fdd_set_type(c, d);
if (fdd_get_type(c) > 13)
fdd_set_type(c, 13);
sprintf(temp, "fdd_%02i_writeprot", c + 1);
ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0);
if (ui_writeprot[c] == 0)
ini_section_delete_var(cat, temp);
sprintf(temp, "fdd_%02i_fn", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "");
2023-08-22 19:06:57 +02:00
if (!strcmp(p, usr_path))
2023-08-22 19:16:18 +02:00
p[0] = 0x00;
2023-08-22 19:06:57 +02:00
if (p[0] != 0x00) {
if (load_image_file(floppyfns[c], p, (uint8_t *) &(ui_writeprot[c])))
fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1);
2023-08-22 19:06:57 +02:00
}
#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2)
if (*p != '\0')
2023-06-28 13:46:28 -04:00
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
#endif
sprintf(temp, "fdd_%02i_turbo", c + 1);
2022-09-10 13:32:46 +02:00
fdd_set_turbo(c, !!ini_section_get_int(cat, temp, 0));
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_check_bpb", c + 1);
2022-09-10 13:32:46 +02:00
fdd_set_check_bpb(c, !!ini_section_get_int(cat, temp, 1));
/* Check whether each value is default, if yes, delete it so that only
non-default values will later be saved. */
if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_type", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
if (strlen(floppyfns[c]) == 0) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_fn", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
if (fdd_get_turbo(c) == 0) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_turbo", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
if (fdd_get_check_bpb(c) == 1) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_check_bpb", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
2023-10-14 00:27:33 +02:00
fdd_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (load_image_file(fdd_image_history[c][i], p, NULL))
fatal("Configuration: Length of fdd_%02i_image_history_%02i is more "
"than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
}
}
}
memset(temp, 0x00, sizeof(temp));
2022-07-21 21:44:55 -04:00
for (c = 0; c < CDROM_NUM; c++) {
sprintf(temp, "cdrom_%02i_host_drive", c + 1);
2024-05-20 02:15:17 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_parameters", c + 1);
d = 0;
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL)
sscanf(p, "%01u, %s", &d, s);
else if (c == 0)
/* If this is the first drive, unmute the audio. */
sscanf("1, none", "%01u, %s", &d, s);
else
sscanf("0, none", "%01u, %s", &d, s);
cdrom[c].sound_on = d;
cdrom[c].bus_type = hdd_string_to_bus(s, 1);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_speed", c + 1);
2022-09-10 13:32:46 +02:00
cdrom[c].speed = ini_section_get_int(cat, temp, 8);
sprintf(temp, "cdrom_%02i_type", c + 1);
2025-08-03 01:30:01 +06:00
p = ini_section_get_string(cat, temp, cdrom[c].bus_type == CDROM_BUS_MKE ? "cr563" : "86cd");
/* TODO: Configuration migration, remove when no longer needed. */
int cdrom_type = cdrom_get_from_internal_name(p);
if (cdrom_type == -1) {
cdrom_type = cdrom_get_from_name(p);
if (cdrom_type == -1)
cdrom_set_type(c, cdrom_get_from_internal_name("86cd"));
else
cdrom_set_type(c, cdrom_type);
} else
cdrom_set_type(c, cdrom_type);
if (cdrom_get_type(c) >= count)
cdrom_set_type(c, count - 1);
if (!strcmp(p, "86cd"))
ini_section_delete_var(cat, temp);
/* Default values, needed for proper operation of the Settings dialog. */
cdrom[c].mke_channel = cdrom[c].ide_channel = cdrom[c].scsi_device_id = c & 3;
if (cdrom[c].bus_type == CDROM_BUS_MKE) {
char *type = cdrom_get_internal_name(cdrom_get_type(c));
if (strstr(type, "cr56") == NULL)
cdrom_set_type(c, cdrom_get_from_internal_name("cr563_075"));
sprintf(temp, "cdrom_%02i_mke_channel", c + 1);
cdrom[c].mke_channel = ini_section_get_int(cat, temp, c & 3);
if (cdrom[c].mke_channel > 3)
cdrom[c].mke_channel = 3;
} else if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
sprintf(tmp2, "%01u:%01u", (c & 3) >> 1, (c & 3) & 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
2022-07-21 21:44:55 -04:00
cdrom[c].ide_channel = (board << 1) + dev;
if (cdrom[c].ide_channel > 7)
cdrom[c].ide_channel = 7;
} else if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c & 3);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
cdrom[c].scsi_device_id = ini_section_get_int(cat, temp, c & 3);
if (cdrom[c].scsi_device_id > 15)
cdrom[c].scsi_device_id = 15;
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
2022-07-21 21:44:55 -04:00
cdrom[c].scsi_device_id = (board << 4) + dev;
}
}
if (cdrom[c].bus_type != CDROM_BUS_MKE) {
sprintf(temp, "cdrom_%02i_mke_channel", c + 1);
ini_section_delete_var(cat, temp);
}
if (cdrom[c].bus_type != CDROM_BUS_ATAPI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
if (cdrom[c].bus_type != CDROM_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_image_path", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "");
2023-08-22 19:06:57 +02:00
if (!strcmp(p, usr_path))
2023-08-22 19:16:18 +02:00
p[0] = 0x00;
2023-08-22 19:06:57 +02:00
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("Configuration: Length of cdrom_%02i_image_path is more than 511\n", c + 1);
2023-08-22 19:06:57 +02:00
else
strncpy(cdrom[c].image_path, p, 511);
} else
path_append_filename(cdrom[c].image_path, usr_path, p);
path_normalize(cdrom[c].image_path);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
2023-10-14 00:27:33 +02:00
cdrom[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("Configuration: Length of cdrom_%02i_image_history_%02i is more "
"than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
else
2024-12-13 06:06:49 +01:00
snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p);
} else
2024-12-13 06:06:49 +01:00
snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(cdrom[c].image_history[i]);
}
}
/* If the CD-ROM is disabled, delete all its variables. */
if (cdrom[c].bus_type == CDROM_BUS_DISABLED) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_parameters", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_speed", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_type", c + 1);
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_image_path", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
ini_section_delete_var(cat, temp);
}
}
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_iso_path", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
}
/* Load "Other Removable Devices" section. */
static void
load_other_removable_devices(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Other removable devices");
2023-05-11 03:02:36 -04:00
char temp[512];
char tmp2[512];
char *p;
2022-09-18 17:11:43 -04:00
char s[512];
2023-05-11 03:02:36 -04:00
unsigned int board = 0;
unsigned int dev = 0;
int c;
int legacy_zip_drives = 0;
2018-01-26 22:17:09 +01:00
memset(temp, 0x00, sizeof(temp));
for (c = 0; c < RDISK_NUM; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_parameters", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL) {
sscanf(p, "%01u, %s", &rdisk_drives[c].type, s);
legacy_zip_drives++;
} else
sscanf("0, none", "%01u, %s", &rdisk_drives[c].type, s);
rdisk_drives[c].type++;
rdisk_drives[c].bus_type = hdd_string_to_bus(s, 1);
/* Default values, needed for proper operation of the Settings dialog. */
rdisk_drives[c].ide_channel = rdisk_drives[c].scsi_device_id = c + 2;
if (rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_ide_channel", c + 1);
sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
rdisk_drives[c].ide_channel = (board << 1) + dev;
if (rdisk_drives[c].ide_channel > 7)
rdisk_drives[c].ide_channel = 7;
} else if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_scsi_location", c + 1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_scsi_id", c + 1);
rdisk_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2);
if (rdisk_drives[c].scsi_device_id > 15)
rdisk_drives[c].scsi_device_id = 15;
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
rdisk_drives[c].scsi_device_id = (board << 4) + dev;
}
}
2018-01-26 22:17:09 +01:00
if (rdisk_drives[c].bus_type != RDISK_BUS_ATAPI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
if (rdisk_drives[c].bus_type != RDISK_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "zip_%02i_image_path", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "");
2025-07-21 01:20:54 +06:00
sprintf(temp, "zip_%02i_writeprot", c + 1);
rdisk_drives[c].read_only = ini_section_get_int(cat, temp, 0);
ini_section_delete_var(cat, temp);
2018-01-26 22:17:09 +01:00
2023-08-22 19:06:57 +02:00
if (!strcmp(p, usr_path))
2023-08-22 19:16:18 +02:00
p[0] = 0x00;
2023-08-22 19:06:57 +02:00
if (p[0] != 0x00) {
if (load_image_file(rdisk_drives[c].image_path, p, &(rdisk_drives[c].read_only)))
fatal("Configuration: Length of zip_%02i_image_path is more than 511\n", c + 1);
2023-08-22 19:06:57 +02:00
}
2018-01-26 22:17:09 +01:00
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
rdisk_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (load_image_file(rdisk_drives[c].image_history[i], p, NULL))
fatal("Configuration: Length of zip_%02i_image_history_%02i is more than %i\n",
c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
}
}
sprintf(temp, "zip_%02i_parameters", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "zip_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "zip_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "zip_%02i_image_path", c + 1);
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
}
2018-01-26 22:17:09 +01:00
if (legacy_zip_drives > 0)
goto go_to_mo;
memset(temp, 0x00, sizeof(temp));
for (c = 0; c < RDISK_NUM; c++) {
sprintf(temp, "rdisk_%02i_parameters", c + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL) {
sscanf(p, "%01u, %s", &rdisk_drives[c].type, s);
legacy_zip_drives++;
} else
sscanf("0, none", "%01u, %s", &rdisk_drives[c].type, s);
rdisk_drives[c].bus_type = hdd_string_to_bus(s, 1);
/* Default values, needed for proper operation of the Settings dialog. */
rdisk_drives[c].ide_channel = rdisk_drives[c].scsi_device_id = c + 2;
if (rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) {
sprintf(temp, "rdisk_%02i_ide_channel", c + 1);
sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1);
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
rdisk_drives[c].ide_channel = (board << 1) + dev;
if (rdisk_drives[c].ide_channel > 7)
rdisk_drives[c].ide_channel = 7;
} else if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) {
sprintf(temp, "rdisk_%02i_scsi_location", c + 1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
sprintf(temp, "rdisk_%02i_scsi_id", c + 1);
rdisk_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2);
if (rdisk_drives[c].scsi_device_id > 15)
rdisk_drives[c].scsi_device_id = 15;
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
rdisk_drives[c].scsi_device_id = (board << 4) + dev;
}
}
if (rdisk_drives[c].bus_type != RDISK_BUS_ATAPI) {
sprintf(temp, "rdisk_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
2018-01-26 22:17:09 +01:00
if (rdisk_drives[c].bus_type != RDISK_BUS_SCSI) {
sprintf(temp, "rdisk_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
sprintf(temp, "rdisk_%02i_scsi_id", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "rdisk_%02i_image_path", c + 1);
p = ini_section_get_string(cat, temp, "");
sprintf(temp, "rdisk_%02i_writeprot", c + 1);
rdisk_drives[c].read_only = ini_section_get_int(cat, temp, 0);
ini_section_delete_var(cat, temp);
if (!strcmp(p, usr_path))
p[0] = 0x00;
if (p[0] != 0x00) {
if (load_image_file(rdisk_drives[c].image_path, p, &(rdisk_drives[c].read_only)))
fatal("Configuration: Length of rdisk_%02i_image_path is more than 511\n", c + 1);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
rdisk_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "rdisk_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (load_image_file(rdisk_drives[c].image_history[i], p, NULL))
fatal("Configuration: Length of rdisk_%02i_image_history_%02i is more than %i\n",
c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
}
}
/* If the removable disk drive is disabled, delete all its variables. */
if (rdisk_drives[c].bus_type == RDISK_BUS_DISABLED) {
sprintf(temp, "rdisk_%02i_parameters", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "rdisk_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "rdisk_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "rdisk_%02i_image_path", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2018-01-26 22:17:09 +01:00
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "rdisk_%02i_image_history_%02i", c + 1, i + 1);
ini_section_delete_var(cat, temp);
}
}
2018-01-26 22:17:09 +01:00
}
go_to_mo:
memset(temp, 0x00, sizeof(temp));
2022-07-21 21:44:55 -04:00
for (c = 0; c < MO_NUM; c++) {
sprintf(temp, "mo_%02i_parameters", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL)
sscanf(p, "%u, %s", &mo_drives[c].type, s);
else
sscanf("00, none", "%u, %s", &mo_drives[c].type, s);
mo_drives[c].bus_type = hdd_string_to_bus(s, 1);
/* Default values, needed for proper operation of the Settings dialog. */
mo_drives[c].ide_channel = mo_drives[c].scsi_device_id = c + 2;
if (mo_drives[c].bus_type == MO_BUS_ATAPI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_ide_channel", c + 1);
sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%01u", &board, &dev);
board &= 3;
dev &= 1;
2022-07-21 21:44:55 -04:00
mo_drives[c].ide_channel = (board << 1) + dev;
if (mo_drives[c].ide_channel > 7)
mo_drives[c].ide_channel = 7;
} else if (mo_drives[c].bus_type == MO_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_scsi_location", c + 1);
sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, tmp2);
sscanf(p, "%01u:%02u", &board, &dev);
if (board >= SCSI_BUS_MAX) {
/* Invalid bus - check legacy ID */
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
mo_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2);
if (mo_drives[c].scsi_device_id > 15)
mo_drives[c].scsi_device_id = 15;
} else {
board %= SCSI_BUS_MAX;
dev &= 15;
2022-07-21 21:44:55 -04:00
mo_drives[c].scsi_device_id = (board << 4) + dev;
}
}
if (mo_drives[c].bus_type != MO_BUS_ATAPI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
if (mo_drives[c].bus_type != MO_BUS_SCSI) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
}
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_image_path", c + 1);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "");
2025-07-21 01:20:54 +06:00
sprintf(temp, "mo_%02i_writeprot", c + 1);
mo_drives[c].read_only = ini_section_get_int(cat, temp, 0);
ini_section_delete_var(cat, temp);
2025-07-21 01:20:54 +06:00
2023-08-22 19:06:57 +02:00
if (!strcmp(p, usr_path))
2023-08-22 19:16:18 +02:00
p[0] = 0x00;
2023-08-22 19:06:57 +02:00
if (p[0] != 0x00) {
if (load_image_file(mo_drives[c].image_path, p, &(mo_drives[c].read_only)))
fatal("Configuration: Length of mo_%02i_image_path is more than 511\n", c + 1);
2023-08-22 19:06:57 +02:00
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
2023-10-14 00:27:33 +02:00
mo_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (load_image_file(mo_drives[c].image_history[i], p, NULL))
fatal("Configuration: Length of mo_%02i_image_history_%02i is more than %i\n",
c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1);
}
}
/* If the MO drive is disabled, delete all its variables. */
if (mo_drives[c].bus_type == MO_BUS_DISABLED) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_parameters", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_ide_channel", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "mo_%02i_scsi_location", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_image_path", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
ini_section_delete_var(cat, temp);
}
}
2022-02-20 02:26:27 -05:00
}
}
/* Load "Other Peripherals" section. */
static void
load_other_peripherals(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_section(config, "Other peripherals");
2022-09-18 17:11:43 -04:00
char *p;
char temp[512];
bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0);
postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0);
unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0);
novell_keycard_enabled = !!ini_section_get_int(cat, "novell_keycard_enabled", 0);
if (!bugger_enabled)
ini_section_delete_var(cat, "bugger_enabled");
if (!postcard_enabled)
ini_section_delete_var(cat, "postcard_enabled");
if (!unittester_enabled)
ini_section_delete_var(cat, "unittester_enabled");
if (!novell_keycard_enabled)
ini_section_delete_var(cat, "novell_keycard_enabled");
2025-05-04 21:44:53 -04:00
// ISA RAM Boards
2023-05-11 03:02:36 -04:00
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
sprintf(temp, "isamem%d_type", c);
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, temp, "none");
isamem_type[c] = isamem_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
2025-05-04 21:44:53 -04:00
// ISA ROM Boards
for (uint8_t c = 0; c < ISAROM_MAX; c++) {
sprintf(temp, "isarom%d_type", c);
p = ini_section_get_string(cat, temp, "none");
isarom_type[c] = isarom_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
/* Backwards compatibility for standalone LBA Enhancer from v4.2 and older. */
if (ini_section_get_int(ini_find_section(config, "Storage controllers"), "lba_enhancer_enabled", 0) == 1) {
/* Migrate to the first available ISA ROM slot. */
for (uint8_t c = 0; c < ISAROM_MAX; c++) {
if (!isarom_type[c]) {
isarom_type[c] = isarom_get_from_internal_name("lba_enhancer");
break;
}
}
}
2022-09-10 13:32:46 +02:00
p = ini_section_get_string(cat, "isartc_type", "none");
2022-02-20 02:26:27 -05:00
isartc_type = isartc_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
#ifndef USE_SDL_UI
2025-03-09 01:39:07 +06:00
/* Load OpenGL 3.0 renderer options. */
static void
load_gl3_shaders(void)
{
ini_section_t cat = ini_find_section(config, "GL3 Shaders");
char *p;
char temp[512];
2025-03-09 23:58:54 +06:00
int i = 0, shaders = 0;
2025-03-09 01:39:07 +06:00
memset(temp, 0, sizeof(temp));
memset(gl3_shader_file, 0, sizeof(gl3_shader_file));
2025-03-09 23:58:54 +06:00
shaders = ini_section_get_int(cat, "shaders", 0);
if (shaders > MAX_USER_SHADERS)
shaders = MAX_USER_SHADERS;
if (shaders == 0) {
ini_section_t general = ini_find_section(config, "General");
if (general) {
p = ini_section_get_string(general, "video_gl_shader", NULL);
if (p) {
if (strlen(p) > 511)
fatal("Configuration: Length of video_gl_shadr is more than 511\n");
else
strncpy(gl3_shader_file[0], p, 511);
ini_delete_var(config, general, "video_gl_shader");
return;
}
}
}
for (i = 0; i < shaders; i++) {
2025-03-09 01:39:07 +06:00
temp[0] = 0;
snprintf(temp, 512, "shader%d", i);
p = ini_section_get_string(cat, temp, "");
if (p[0]) {
strncpy(gl3_shader_file[i], p, 512);
} else {
gl3_shader_file[i][0] = 0;
break;
}
}
}
#endif
2025-03-09 01:39:07 +06:00
2025-04-19 19:44:47 -07:00
/* Load "Keybinds" section. */
static void
load_keybinds(void)
{
ini_section_t cat = ini_find_section(config, "Keybinds");
char *p;
char temp[512];
memset(temp, 0, sizeof(temp));
/* Now load values from config */
for (int x = 0; x < NUM_ACCELS; x++) {
p = ini_section_get_string(cat, acc_keys[x].name, "default");
/* Check if the binding was marked as cleared */
if (strcmp(p, "none") == 0)
acc_keys[x].seq[0] = '\0';
/* If there's no binding in the file, leave it alone. */
else if (strcmp(p, "default") != 0) {
/*
It would be ideal to validate whether the user entered a
valid combo at this point, but the Qt method for testing that is
not available from C. Fortunately, if you feed Qt an invalid
keysequence string it just assigns nothing, so this won't blow up.
However, to improve the user experience, we should validate keys
and erase any bad combos from config on mainwindow load.
*/
strcpy(acc_keys[x].seq, p);
}
}
2025-04-19 19:44:47 -07:00
}
/* Load the specified or a default configuration file. */
void
config_load(void)
{
int i;
ini_section_t c;
config_log("Loading config file '%s'..\n", cfg_path);
memset(hdd, 0, sizeof(hard_disk_t));
memset(cdrom, 0, sizeof(cdrom_t) * CDROM_NUM);
#ifdef USE_IOCTL
memset(cdrom_ioctl, 0, sizeof(cdrom_ioctl_t) * CDROM_NUM);
#endif
memset(rdisk_drives, 0, sizeof(rdisk_drive_t));
2022-09-10 13:32:46 +02:00
config = ini_read(cfg_path);
if (config == NULL) {
2022-09-10 13:32:46 +02:00
config = ini_new();
config_changed = 1;
cpu_f = (cpu_family_t *) &cpu_families[0];
2022-07-21 21:44:55 -04:00
cpu = 0;
kbd_req_capture = 0;
hide_status_bar = 0;
2022-07-21 21:44:55 -04:00
hide_tool_bar = 0;
scale = 1;
machine = machine_get_machine_from_internal_name("ibmpc");
dpi_scale = 1;
do_auto_pause = 0;
2022-07-21 21:44:55 -04:00
2024-04-25 19:14:51 +02:00
cpu_override_interpreter = 0;
2022-07-21 21:44:55 -04:00
fpu_type = fpu_get_type(cpu_f, cpu, "none");
2023-02-06 04:12:46 -05:00
gfxcard[0] = video_get_video_from_internal_name("cga");
2022-07-21 21:44:55 -04:00
vid_api = plat_vidapi("default");
vid_resize = 0;
video_fullscreen_scale = 1;
2022-07-21 21:44:55 -04:00
time_sync = TIME_SYNC_ENABLED;
2025-07-27 15:23:43 +02:00
keyboard_type = KEYBOARD_TYPE_PC_XT;
for (int i = 0; i < HDC_MAX; i++)
hdc_current[i] = hdc_get_from_internal_name("none");
2022-07-28 16:50:49 -04:00
com_ports[0].enabled = 1;
com_ports[1].enabled = 1;
for (i = 2; i < (SERIAL_MAX - 1); i++)
2022-07-28 16:50:49 -04:00
com_ports[i].enabled = 0;
lpt_ports[0].enabled = 1;
2022-07-21 21:44:55 -04:00
for (i = 1; i < PARALLEL_MAX; i++)
lpt_ports[i].enabled = 0;
for (i = 0; i < FDD_NUM; i++) {
if (i < 2)
fdd_set_type(i, 2);
else
fdd_set_type(i, 0);
fdd_set_turbo(i, 0);
fdd_set_check_bpb(i, 1);
}
2020-11-09 04:24:33 +05:00
/* Unmute the CD audio on the first CD-ROM drive. */
cdrom[0].sound_on = 1;
2022-07-21 21:44:55 -04:00
mem_size = 64;
isartc_type = 0;
2025-05-04 21:44:53 -04:00
for (i = 0; i < ISAROM_MAX; i++)
isarom_type[i] = 0;
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = 0;
cassette_enable = 1;
memset(cassette_fname, 0x00, sizeof(cassette_fname));
memcpy(cassette_mode, "load", strlen("load") + 1);
2022-07-21 21:44:55 -04:00
cassette_pos = 0;
cassette_srate = 44100;
cassette_append = 0;
cassette_pcm = 0;
cassette_ui_writeprot = 0;
lang_id = plat_language_code(DEFAULT_LANGUAGE);
config_log("Config file not present or invalid!\n");
} else {
load_general(); /* General */
for (i = 0; i < MONITORS_NUM; i++)
load_monitor(i); /* Monitors */
load_machine(); /* Machine */
load_video(); /* Video */
load_input_devices(); /* Input devices */
load_sound(); /* Sound */
load_network(); /* Network */
load_ports(); /* Ports (COM & LPT) */
load_storage_controllers(); /* Storage controllers */
load_hard_disks(); /* Hard disks */
load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
load_other_removable_devices(); /* Other removable devices */
load_other_peripherals(); /* Other peripherals */
#ifndef USE_SDL_UI
2025-03-09 01:39:07 +06:00
load_gl3_shaders(); /* GL3 Shaders */
#endif
load_keybinds(); /* Load shortcut keybinds */
/* Migrate renamed device configurations. */
c = ini_find_section(config, "MDA");
if (c != NULL)
ini_rename_section(c, "IBM MDA");
c = ini_find_section(config, "CGA");
if (c != NULL)
ini_rename_section(c, "IBM CGA");
c = ini_find_section(config, "EGA");
if (c != NULL)
ini_rename_section(c, "IBM EGA");
c = ini_find_section(config, "3DFX Voodoo Graphics");
if (c != NULL)
ini_rename_section(c, "3Dfx Voodoo Graphics");
c = ini_find_section(config, "3dfx Voodoo Banshee");
if (c != NULL)
ini_rename_section(c, "3Dfx Voodoo Banshee");
/* Mark the configuration as changed. */
config_changed = 1;
config_log("Config loaded.\n\n");
}
video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy;
}
/* Save "General" section. */
static void
save_general(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "General");
2023-05-11 03:02:36 -04:00
char temp[512];
char buffer[512] = { 0 };
const char *va_name;
ini_section_set_int(cat, "force_10ms", force_10ms);
if (force_10ms == 0)
ini_section_delete_var(cat, "force_10ms");
ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys);
if (inhibit_multimedia_keys == 0)
ini_section_delete_var(cat, "inhibit_multimedia_keys");
2025-03-07 00:36:09 +06:00
ini_section_set_int(cat, "sound_muted", sound_muted);
if (sound_muted == 0)
ini_section_delete_var(cat, "sound_muted");
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "vid_resize", vid_resize);
if (vid_resize == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "vid_resize");
va_name = plat_vidapi_name(vid_api);
2022-07-18 02:17:16 +02:00
if (!strcmp(va_name, "default"))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "vid_renderer");
2022-07-18 02:17:16 +02:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "vid_renderer", va_name);
if (video_fullscreen_scale == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_fullscreen_scale");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale);
if (video_filter_method == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_filter_method");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_filter_method", video_filter_method);
if (force_43 == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "force_43");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "force_43", force_43);
if (scale == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "scale");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "scale", scale);
if (dpi_scale == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "dpi_scale");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "dpi_scale", dpi_scale);
if (enable_overscan == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "enable_overscan");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "enable_overscan", enable_overscan);
if (vid_cga_contrast == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "vid_cga_contrast");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "vid_cga_contrast", vid_cga_contrast);
if (video_grayscale == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_grayscale");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_grayscale", video_grayscale);
if (video_graytype == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_graytype");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_graytype", video_graytype);
if (rctrl_is_lalt == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "rctrl_is_lalt");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "rctrl_is_lalt", rctrl_is_lalt);
if (update_icons == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "update_icons");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "update_icons", update_icons);
if (window_remember)
ini_section_set_int(cat, "window_remember", window_remember);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "window_remember");
if (vid_resize & 2) {
sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "window_fixed_res", temp);
} else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "window_fixed_res");
if (sound_gain != 0)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "sound_gain", sound_gain);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "sound_gain");
if (kbd_req_capture != 0)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "kbd_req_capture", kbd_req_capture);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "kbd_req_capture");
if (hide_status_bar != 0)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "hide_status_bar", hide_status_bar);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "hide_status_bar");
if (hide_tool_bar != 0)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "hide_tool_bar", hide_tool_bar);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "hide_tool_bar");
if (confirm_reset != 1)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "confirm_reset", confirm_reset);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "confirm_reset");
if (confirm_exit != 1)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "confirm_exit", confirm_exit);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "confirm_exit");
if (confirm_save != 1)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "confirm_save", confirm_save);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "confirm_save");
2022-06-01 15:31:58 +06:00
if (mouse_sensitivity != 1.0)
2022-09-10 13:32:46 +02:00
ini_section_set_double(cat, "mouse_sensitivity", mouse_sensitivity);
2022-06-01 15:31:58 +06:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "mouse_sensitivity");
if (lang_id == plat_language_code(DEFAULT_LANGUAGE))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "language");
2022-07-18 02:17:16 +02:00
else {
plat_language_code_r(lang_id, buffer, 511);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "language", buffer);
2022-07-18 02:17:16 +02:00
}
2019-12-04 21:55:35 +01:00
if (enable_discord)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "enable_discord", enable_discord);
2019-12-04 21:55:35 +01:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "enable_discord");
2019-12-04 21:55:35 +01:00
if (open_dir_usr_path)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "open_dir_usr_path", open_dir_usr_path);
2019-12-04 21:55:35 +01:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "open_dir_usr_path");
2019-12-04 21:55:35 +01:00
if (video_framerate != -1)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_gl_framerate", video_framerate);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_gl_framerate");
if (video_vsync != 0)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_gl_vsync", video_vsync);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_gl_vsync");
if (do_auto_pause)
ini_section_set_int(cat, "do_auto_pause", do_auto_pause);
else
ini_section_delete_var(cat, "do_auto_pause");
char cpu_buf[128] = { 0 };
plat_get_cpu_string(cpu_buf, 128);
ini_section_set_string(cat, "host_cpu", cpu_buf);
if (EMU_BUILD_NUM != 0)
ini_section_set_int(cat, "emu_build_num", EMU_BUILD_NUM);
else
ini_section_delete_var(cat, "emu_build_num");
if (strnlen(uuid, sizeof(uuid) - 1) > 0)
ini_section_set_string(cat, "uuid", uuid);
else
ini_section_delete_var(cat, "uuid");
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save monitor section. */
static void
save_monitor(int monitor_index)
{
ini_section_t cat;
char name[sizeof("Monitor #") + 12] = { [0] = 0 };
char temp[512];
monitor_settings_t *ms = &monitor_settings[monitor_index];
snprintf(name, sizeof(name), "Monitor #%i", monitor_index + 1);
cat = ini_find_or_create_section(config, name);
if (window_remember) {
sprintf(temp, "%i, %i, %i, %i", ms->mon_window_x, ms->mon_window_y,
ms->mon_window_w, ms->mon_window_h);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "window_coordinates", temp);
if (ms->mon_window_maximized != 0)
ini_section_set_int(cat, "window_maximized", ms->mon_window_maximized);
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "window_maximized");
} else {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "window_coordinates");
ini_section_delete_var(cat, "window_maximized");
}
ini_delete_section_if_empty(config, cat);
}
/* Save "Machine" section. */
static void
save_machine(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Machine");
2023-07-20 18:58:26 -04:00
const char *p;
p = machine_get_internal_name();
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "machine", p);
2023-06-09 23:46:54 -04:00
ini_section_set_string(cat, "cpu_family", cpu_f->internal_name);
ini_section_set_uint(cat, "cpu_speed", cpu_f->cpus[cpu].rspeed);
2022-09-10 13:32:46 +02:00
ini_section_set_double(cat, "cpu_multi", cpu_f->cpus[cpu].multi);
2020-11-23 14:48:32 -03:00
if (cpu_override)
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cpu_override", cpu_override);
2020-11-23 14:48:32 -03:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cpu_override");
2024-04-25 19:14:51 +02:00
if (cpu_override_interpreter)
ini_section_set_int(cat, "cpu_override_interpreter", cpu_override_interpreter);
2024-04-25 19:14:51 +02:00
else
ini_section_delete_var(cat, "cpu_override_interpreter");
/* Downgrade compatibility with the previous CPU model system. */
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cpu_manufacturer");
ini_section_delete_var(cat, "cpu");
if (cpu_waitstates == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cpu_waitstates");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cpu_waitstates", cpu_waitstates);
if (fpu_type == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "fpu_type");
else
2023-06-09 23:46:54 -04:00
ini_section_set_string(cat, "fpu_type", fpu_get_internal_name(cpu_f, cpu, fpu_type));
/* Write the mem_size explicitly to the setttings in order to help managers
to display it without having the actual machine table. */
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "mem_size", mem_size);
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec);
if (fpu_softfloat == 0)
ini_section_delete_var(cat, "fpu_softfloat");
else
ini_section_set_int(cat, "fpu_softfloat", fpu_softfloat);
if (time_sync & TIME_SYNC_ENABLED)
if (time_sync & TIME_SYNC_UTC)
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "time_sync", "utc");
else
ini_section_delete_var(cat, "time_sync");
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "time_sync", "disabled");
if (pit_mode == -1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "pit_mode");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "pit_mode", pit_mode);
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save "Video" section. */
static void
save_video(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Video");
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "gfxcard",
2023-02-06 04:12:46 -05:00
video_get_internal_name(gfxcard[0]));
if (voodoo_enabled == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "voodoo");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "voodoo", voodoo_enabled);
if (ibm8514_standalone_enabled == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "8514a");
else
ini_section_set_int(cat, "8514a", ibm8514_standalone_enabled);
if (xga_standalone_enabled == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "xga");
else
ini_section_set_int(cat, "xga", xga_standalone_enabled);
if (da2_standalone_enabled == 0)
ini_section_delete_var(cat, "da2");
else
ini_section_set_int(cat, "da2", da2_standalone_enabled);
// TODO
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
if (gfxcard[i] == 0)
ini_section_delete_var(cat, "gfxcard_2");
else
ini_section_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard[i]));
}
2022-07-04 01:50:42 +06:00
if (show_second_monitors == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "show_second_monitors");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "show_second_monitors", show_second_monitors);
if (video_fullscreen_scale_maximized == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "video_fullscreen_scale_maximized");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "video_fullscreen_scale_maximized", video_fullscreen_scale_maximized);
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save "Input Devices" section. */
static void
save_input_devices(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Input devices");
2023-05-11 03:02:36 -04:00
char temp[512];
char tmp2[512];
2025-07-27 15:23:43 +02:00
ini_section_set_string(cat, "keyboard_type", keyboard_get_internal_name(keyboard_type));
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type));
if (!joystick_type) {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "joystick_type");
2025-01-11 01:31:57 -05:00
for (int js = 0; js < MAX_PLAT_JOYSTICKS; js++) {
sprintf(tmp2, "joystick_%i_nr", js);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, tmp2);
2025-01-11 03:39:15 -05:00
for (int axis_nr = 0; axis_nr < MAX_JOY_AXES; axis_nr++) {
2025-01-11 01:31:57 -05:00
sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, tmp2);
}
2025-01-11 03:39:15 -05:00
for (int button_nr = 0; button_nr < MAX_JOY_BUTTONS; button_nr++) {
2025-01-11 01:31:57 -05:00
sprintf(tmp2, "joystick_%i_button_%i", js, button_nr);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, tmp2);
}
2025-01-11 03:39:15 -05:00
for (int pov_nr = 0; pov_nr < MAX_JOY_POVS; pov_nr++) {
2025-01-11 01:31:57 -05:00
sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, tmp2);
}
}
} else {
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type));
2025-01-11 01:31:57 -05:00
for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) {
sprintf(tmp2, "joystick_%i_nr", js);
ini_section_set_int(cat, tmp2, joystick_state[0][js].plat_joystick_nr);
if (joystick_state[0][js].plat_joystick_nr) {
2025-01-11 01:31:57 -05:00
for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) {
sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr);
ini_section_set_int(cat, tmp2, joystick_state[0][js].axis_mapping[axis_nr]);
}
2025-01-11 01:31:57 -05:00
for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) {
sprintf(tmp2, "joystick_%i_button_%i", js, button_nr);
ini_section_set_int(cat, tmp2, joystick_state[0][js].button_mapping[button_nr]);
}
2025-01-11 01:31:57 -05:00
for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) {
sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr);
sprintf(temp, "%i, %i", joystick_state[0][js].pov_mapping[pov_nr][0],
joystick_state[0][js].pov_mapping[pov_nr][1]);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, tmp2, temp);
}
}
}
}
2023-01-03 15:42:57 +06:00
if (tablet_tool_type != 1) {
ini_section_set_int(cat, "tablet_tool_type", tablet_tool_type);
} else {
ini_section_delete_var(cat, "tablet_tool_type");
}
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save "Sound" section. */
static void
save_sound(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Sound");
2023-02-01 02:31:07 -05:00
if (sound_card_current[0] == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "sndcard");
else
2023-02-01 02:31:07 -05:00
ini_section_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current[0]));
2023-02-01 02:31:07 -05:00
if (sound_card_current[1] == 0)
ini_section_delete_var(cat, "sndcard2");
else
ini_section_set_string(cat, "sndcard2", sound_card_get_internal_name(sound_card_current[1]));
2023-02-01 02:31:07 -05:00
if (sound_card_current[2] == 0)
ini_section_delete_var(cat, "sndcard3");
else
ini_section_set_string(cat, "sndcard3", sound_card_get_internal_name(sound_card_current[2]));
2020-01-01 20:20:16 +01:00
2023-02-01 02:31:07 -05:00
if (sound_card_current[3] == 0)
ini_section_delete_var(cat, "sndcard4");
else
ini_section_set_string(cat, "sndcard4", sound_card_get_internal_name(sound_card_current[3]));
if (!strcmp(midi_out_device_get_internal_name(midi_output_device_current), "none"))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "midi_device");
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "midi_device", midi_out_device_get_internal_name(midi_output_device_current));
2020-01-01 20:20:16 +01:00
if (!strcmp(midi_in_device_get_internal_name(midi_input_device_current), "none"))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "midi_in_device");
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "midi_in_device", midi_in_device_get_internal_name(midi_input_device_current));
if (mpu401_standalone_enable == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "mpu401_standalone");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "mpu401_standalone", mpu401_standalone_enable);
/* Downgrade compatibility for standalone SSI-2001, CMS and GUS from v3.11 and older. */
2023-04-18 16:16:42 -03:00
const char *legacy_cards[][2] = {
{"ssi2001", "ssi2001"},
{ "gameblaster", "cms" },
{ "gus", "gus" }
};
for (int i = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) {
int card_id = sound_card_get_from_internal_name(legacy_cards[i][1]);
for (int j = 0; j < (sizeof(sound_card_current) / sizeof(sound_card_current[0])); j++) {
if (sound_card_current[j] == card_id) {
/* A special value of 2 still enables the cards on older versions,
but lets newer versions know that they've already been migrated. */
ini_section_set_int(cat, legacy_cards[i][0], 2);
card_id = 0; /* mark as found */
break;
}
}
if (card_id > 0) /* not found */
ini_section_delete_var(cat, legacy_cards[i][0]);
}
if (sound_is_float == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "sound_type");
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "sound_type", (sound_is_float == 1) ? "float" : "int16");
if (fm_driver == FM_DRV_NUKED)
ini_section_delete_var(cat, "fm_driver");
else
ini_section_set_string(cat, "fm_driver", "ymfm");
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save "Network" section. */
static void
save_network(void)
{
char temp[512];
ini_section_t cat = ini_find_or_create_section(config, "Network");
netcard_conf_t *nc;
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "net_type");
ini_section_delete_var(cat, "net_host_device");
ini_section_delete_var(cat, "net_card");
2023-05-11 03:02:36 -04:00
for (uint8_t c = 0; c < NET_CARD_MAX; c++) {
nc = &net_cards_conf[c];
sprintf(temp, "net_%02i_card", c + 1);
if (nc->device_num == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, network_card_get_internal_name(nc->device_num));
sprintf(temp, "net_%02i_net_type", c + 1);
switch(nc->net_type) {
case NET_TYPE_NONE:
ini_section_delete_var(cat, temp);
break;
case NET_TYPE_SLIRP:
ini_section_set_string(cat, temp, "slirp");
break;
case NET_TYPE_PCAP:
ini_section_set_string(cat, temp, "pcap");
break;
case NET_TYPE_VDE:
ini_section_set_string(cat, temp, "vde");
break;
case NET_TYPE_TAP:
ini_section_set_string(cat, temp, "tap");
break;
2023-06-28 13:46:28 -04:00
default:
break;
}
sprintf(temp, "net_%02i_host_device", c + 1);
if (nc->host_dev_name[0] != '\0') {
if (!strcmp(nc->host_dev_name, "none"))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, nc->host_dev_name);
} else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
sprintf(temp, "net_%02i_link", c + 1);
if (nc->link_state == (NET_LINK_10_HD | NET_LINK_10_FD |
NET_LINK_100_HD | NET_LINK_100_FD |
NET_LINK_1000_HD | NET_LINK_1000_FD))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
ini_section_set_int(cat, temp, nc->link_state);
}
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save "Ports" section. */
static void
save_ports(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)");
2022-09-18 17:11:43 -04:00
char temp[512];
for (int c = 0; c < (SERIAL_MAX - 1); c++) {
sprintf(temp, "serial%d_enabled", c + 1);
2022-07-28 16:50:49 -04:00
if (((c < 2) && com_ports[c].enabled) || ((c >= 2) && !com_ports[c].enabled))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, com_ports[c].enabled);
2022-01-31 01:43:12 -05:00
2023-02-16 22:43:33 +06:00
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
if (serial_passthrough_enabled[c])
2023-02-16 22:43:33 +06:00
ini_section_set_int(cat, temp, 1);
else
2023-02-16 22:43:33 +06:00
ini_section_delete_var(cat, temp);
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
}
2025-01-11 01:31:57 -05:00
for (int c = 0; c < PARALLEL_MAX; c++) {
sprintf(temp, "lpt%d_enabled", c + 1);
2025-01-11 01:31:57 -05:00
int d = (c == 0) ? 1 : 0;
if (lpt_ports[c].enabled == d)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, lpt_ports[c].enabled);
sprintf(temp, "lpt%d_device", c + 1);
if (lpt_ports[c].device == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
2025-08-02 14:51:28 +02:00
ini_section_set_string(cat, temp, lpt_device_get_internal_name(lpt_ports[c].device));
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
}
2024-11-30 18:48:22 -05:00
#if 0
// TODO: Save
for (c = 0; c < GAMEPORT_MAX; c++) {
sprintf(temp, "gameport%d_enabled", c + 1);
d = (c == 0) ? 1 : 0;
if (game_ports[c].enabled == d)
ini_section_delete_var(cat, temp);
else
ini_section_set_int(cat, temp, game_ports[c].enabled);
sprintf(temp, "gameport%d_device", c + 1);
if (game_ports[c].device == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
gameport_get_internal_name(game_ports[c].device));
}
for (uint8_t c = 0; c < GAMEPORT_MAX; c++) {
sprintf(temp, "gameport%d_enabled", c);
if (gameport_type[c] == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
gameport_get_internal_name(gameport_type[c]));
}
#endif
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
2025-04-19 19:44:47 -07:00
/* Save "Keybinds" section. */
static void
save_keybinds(void)
{
ini_section_t cat = ini_find_or_create_section(config, "Keybinds");
for (int x = 0; x < NUM_ACCELS; x++) {
/* Has accelerator been changed from default? */
if (strcmp(def_acc_keys[x].seq, acc_keys[x].seq) == 0)
ini_section_delete_var(cat, acc_keys[x].name);
/* Check for a cleared binding to avoid saving it as an empty string */
else if (acc_keys[x].seq[0] == '\0')
ini_section_set_string(cat, acc_keys[x].name, "none");
else
ini_section_set_string(cat, acc_keys[x].name, acc_keys[x].seq);
}
2025-04-19 19:44:47 -07:00
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
static void
save_image_file(char *cat, char *var, char *src)
{
char temp[2048] = { 0 };
char *prefix = "";
path_normalize(src);
if (strstr(src, "wp://") == src) {
src += 5;
prefix = "wp://";
}
if (!strnicmp(src, usr_path, strlen(usr_path)))
sprintf(temp, "%s%s", prefix, &src[strlen(usr_path)]);
else
sprintf(temp, "%s%s", prefix, src);
ini_section_set_string(cat, var, temp);
}
/* Save "Storage Controllers" section. */
static void
save_storage_controllers(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Storage controllers");
2022-09-18 17:11:43 -04:00
char temp[512];
int c;
char *def_hdc;
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "scsicard");
for (c = 0; c < SCSI_CARD_MAX; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "scsicard_%d", c + 1);
2022-07-21 21:44:55 -04:00
if (scsi_card_current[c] == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp,
2022-09-18 17:11:43 -04:00
scsi_card_get_internal_name(scsi_card_current[c]));
}
if (fdc_current[0] == FDC_INTERNAL)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "fdc");
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "fdc",
fdc_card_get_internal_name(fdc_current[0]));
ini_section_delete_var(cat, "hdc");
for (c = 0; c < HDC_MAX; c++) {
sprintf(temp, "hdc_%d", c + 1);
if ((c == 0) && machine_has_flags(machine, MACHINE_HDC))
def_hdc = "internal";
else
def_hdc = "none";
if (!strcmp(hdc_get_internal_name(hdc_current[c]), def_hdc))
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
hdc_get_internal_name(hdc_current[c]));
}
/* Downgrade compatibility for standalone tertiary/quaternary IDE from v4.2 and older. */
const char *legacy_cards[] = { "ide_ter", "ide_qua" };
for (int i = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) {
int card_id = hdc_get_from_internal_name(legacy_cards[i]);
for (int j = 0; j < (sizeof(sound_card_current) / sizeof(sound_card_current[0])); j++) {
if (hdc_current[j] == card_id) {
/* A special value of 2 still enables the cards on older versions,
but lets newer versions know that they've already been migrated. */
ini_section_set_int(cat, legacy_cards[i], 2);
card_id = 0; /* mark as found */
break;
}
}
if (card_id > 0) /* not found */
ini_section_delete_var(cat, legacy_cards[i]);
}
if (cdrom_interface_current == 0)
ini_section_delete_var(cat, "cdrom_interface");
else
ini_section_set_string(cat, "cdrom_interface",
2023-02-28 23:24:58 -05:00
cdrom_interface_get_internal_name(cdrom_interface_current));
if (cassette_enable == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_enabled");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cassette_enabled", cassette_enable);
if (strlen(cassette_fname) == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_file");
else
save_image_file(cat, "cassette_file", cassette_fname);
if (!strcmp(cassette_mode, "load"))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_mode");
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "cassette_mode", cassette_mode);
2024-08-27 03:29:37 +02:00
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cassette_image_history_%02i", i + 1);
if ((cassette_image_history[i] == 0) || strlen(cassette_image_history[i]) == 0)
ini_section_delete_var(cat, temp);
else
save_image_file(cat, temp, cassette_image_history[i]);
2024-08-27 03:29:37 +02:00
}
if (cassette_pos == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_position");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cassette_position", cassette_pos);
if (cassette_srate == 44100)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_srate");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cassette_srate", cassette_srate);
if (cassette_append == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_append");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cassette_append", cassette_append);
if (cassette_pcm == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "cassette_pcm");
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "cassette_pcm", cassette_pcm);
2021-07-28 00:58:19 +02:00
ini_section_delete_var(cat, "cassette_writeprot");
2021-07-29 20:34:55 +02:00
2022-07-21 21:44:55 -04:00
for (c = 0; c < 2; c++) {
sprintf(temp, "cartridge_%02i_fn", c + 1);
2024-08-27 03:29:37 +02:00
2022-07-21 21:44:55 -04:00
if (strlen(cart_fns[c]) == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2024-08-27 03:29:37 +02:00
else {
path_normalize(cart_fns[c]);
if (!strnicmp(cart_fns[c], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cart_fns[c][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cart_fns[c]);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
if ((cart_image_history[c][i] == 0) || strlen(cart_image_history[c][i]) == 0)
ini_section_delete_var(cat, temp);
else {
path_normalize(cart_image_history[c][i]);
if (!strnicmp(cart_image_history[c][i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cart_image_history[c][i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cart_image_history[c][i]);
}
}
2021-07-29 20:34:55 +02:00
}
2024-03-06 15:10:51 +06:00
/* Downgrade compatibility for standalone LBA Enhancer from v4.2 and older. */
int card_id = isarom_get_from_internal_name("lba_enhancer");
for (c = 0; c < ISAROM_MAX; c++) {
if (isarom_type[c] == card_id) {
/* A special value of 2 still enables the cards on older versions,
but lets newer versions know that they've already been migrated. */
ini_section_set_int(cat, "lba_enhancer_enabled", 2);
card_id = 0; /* mark as found */
break;
}
}
if (card_id > 0) /* not found */
2024-03-06 15:10:51 +06:00
ini_section_delete_var(cat, "lba_enhancer_enabled");
ini_delete_section_if_empty(config, cat);
}
/* Save "Other Peripherals" section. */
static void
save_other_peripherals(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Other peripherals");
2022-09-18 17:11:43 -04:00
char temp[512];
if (bugger_enabled == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "bugger_enabled");
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "bugger_enabled", bugger_enabled);
2020-03-23 17:03:28 -03:00
if (postcard_enabled == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "postcard_enabled");
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, "postcard_enabled", postcard_enabled);
2020-03-23 17:03:28 -03:00
if (unittester_enabled == 0)
ini_section_delete_var(cat, "unittester_enabled");
else
ini_section_set_int(cat, "unittester_enabled", unittester_enabled);
if (novell_keycard_enabled == 0)
ini_section_delete_var(cat, "novell_keycard_enabled");
else
ini_section_set_int(cat, "novell_keycard_enabled", novell_keycard_enabled);
2025-05-04 21:44:53 -04:00
// ISA RAM Boards
2023-05-11 03:02:36 -04:00
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "isamem%d_type", c);
if (isamem_type[c] == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp,
2023-06-09 23:46:54 -04:00
isamem_get_internal_name(isamem_type[c]));
}
2025-05-04 21:44:53 -04:00
// ISA ROM Boards
for (uint8_t c = 0; c < ISAROM_MAX; c++) {
sprintf(temp, "isarom%d_type", c);
if (isarom_type[c] == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp,
isarom_get_internal_name(isarom_type[c]));
}
if (isartc_type == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, "isartc_type");
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, "isartc_type",
2022-09-18 17:11:43 -04:00
isartc_get_internal_name(isartc_type));
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
#ifndef USE_SDL_UI
2025-03-09 01:39:07 +06:00
/* Save "GL3 Shaders" section. */
static void
save_gl3_shaders(void)
{
ini_section_t cat = ini_find_or_create_section(config, "GL3 Shaders");
char temp[512];
int shaders = 0, i = 0;
for (i = 0; i < MAX_USER_SHADERS; i++) {
2025-03-09 23:58:54 +06:00
if (gl3_shader_file[i][0] == 0) {
temp[0] = 0;
snprintf(temp, 512, "shader%d", i);
ini_section_delete_var(cat, temp);
2025-03-09 01:39:07 +06:00
break;
2025-03-09 23:58:54 +06:00
}
2025-03-09 01:39:07 +06:00
shaders++;
}
ini_section_set_int(cat, "shaders", shaders);
if (shaders == 0) {
ini_section_delete_var(cat, "shaders");
} else {
for (i = 0; i < shaders; i++) {
temp[0] = 0;
2025-03-09 01:58:47 +06:00
snprintf(temp, 512, "shader%d", i);
2025-03-09 01:39:07 +06:00
ini_section_set_string(cat, temp, gl3_shader_file[i]);
}
}
ini_delete_section_if_empty(config, cat);
}
#endif
2025-03-09 01:39:07 +06:00
/* Save "Hard Disks" section. */
static void
save_hard_disks(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Hard disks");
2023-05-11 03:02:36 -04:00
char temp[32];
char tmp2[512];
2022-09-18 17:11:43 -04:00
char *p;
memset(temp, 0x00, sizeof(temp));
2023-05-11 03:02:36 -04:00
for (uint8_t c = 0; c < HDD_NUM; c++) {
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_parameters", c + 1);
if (hdd_is_valid(c)) {
p = hdd_bus_to_string(hdd[c].bus_type, 0);
2022-07-21 21:44:55 -04:00
sprintf(tmp2, "%u, %u, %u, %i, %s",
hdd[c].spt, hdd[c].hpc, hdd[c].tracks, hdd[c].wp, p);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
} else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_MFM))
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, hdd[c].mfm_channel);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_xta_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_XTA))
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, hdd[c].xta_channel);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_esdi_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_ESDI))
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, hdd[c].esdi_channel);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
if (!hdd_is_valid(c) || ((hdd[c].bus_type != HDD_BUS_IDE) &&
(hdd[c].bus_type != HDD_BUS_ATAPI)))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else {
2022-07-21 21:44:55 -04:00
sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "hdd_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
if (hdd[c].bus_type != HDD_BUS_SCSI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%02u", hdd[c].scsi_id >> 4,
hdd[c].scsi_id & 15);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_fn", c + 1);
if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) {
path_normalize(hdd[c].fn);
if (!strnicmp(hdd[c].fn, usr_path, strlen(usr_path)))
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, &hdd[c].fn[strlen(usr_path)]);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, hdd[c].fn);
2022-07-21 21:44:55 -04:00
} else
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1);
if (hdd_is_valid(c) && (hdd[c].vhd_blocksize > 0))
ini_section_set_int(cat, temp, hdd[c].vhd_blocksize);
else
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_vhd_parent", c + 1);
if (hdd_is_valid(c) && hdd[c].vhd_parent[0]) {
path_normalize(hdd[c].vhd_parent);
ini_section_set_string(cat, temp, hdd[c].vhd_parent);
} else
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "hdd_%02i_speed", c + 1);
if (!hdd_is_valid(c) ||
((hdd[c].bus_type != HDD_BUS_ESDI) && (hdd[c].bus_type != HDD_BUS_IDE) &&
(hdd[c].bus_type != HDD_BUS_SCSI) && (hdd[c].bus_type != HDD_BUS_ATAPI)))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else
2023-06-09 23:46:54 -04:00
ini_section_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset));
}
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
2018-01-26 22:17:09 +01:00
/* Save "Floppy Drives" section. */
static void
save_floppy_and_cdrom_drives(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Floppy and CD-ROM drives");
2023-05-11 03:02:36 -04:00
char temp[512];
char tmp2[512];
2022-09-18 17:11:43 -04:00
int c;
2022-07-21 21:44:55 -04:00
for (c = 0; c < FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c + 1);
if (fdd_get_type(c) == ((c < 2) ? 2 : 0))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp,
2022-09-18 17:11:43 -04:00
fdd_get_internal_name(fdd_get_type(c)));
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_fn", c + 1);
if (strlen(floppyfns[c]) == 0) {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
ui_writeprot[c] = 0;
sprintf(temp, "fdd_%02i_writeprot", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
} else
save_image_file(cat, temp, floppyfns[c]);
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_writeprot", c + 1);
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_turbo", c + 1);
if (fdd_get_turbo(c) == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, fdd_get_turbo(c));
2022-07-21 21:44:55 -04:00
sprintf(temp, "fdd_%02i_check_bpb", c + 1);
if (fdd_get_check_bpb(c) == 1)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, fdd_get_check_bpb(c));
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0)
ini_section_delete_var(cat, temp);
else
save_image_file(cat, temp, fdd_image_history[c][i]);
}
}
2022-07-21 21:44:55 -04:00
for (c = 0; c < CDROM_NUM; c++) {
sprintf(temp, "cdrom_%02i_host_drive", c + 1);
2024-05-20 02:15:17 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_speed", c + 1);
if ((cdrom[c].bus_type == 0) || (cdrom[c].speed == 8))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
2022-09-10 13:32:46 +02:00
ini_section_set_int(cat, temp, cdrom[c].speed);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_type", c + 1);
char *tn = cdrom_get_internal_name(cdrom_get_type(c));
if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || !strcmp(tn, "86cd"))
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, tn);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_parameters", c + 1);
if (cdrom[c].bus_type == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else {
/* In case one wants an ATAPI drive on SCSI and vice-versa. */
if ((cdrom_drive_types[cdrom_get_type(c)].bus_type != BUS_TYPE_BOTH) &&
(cdrom_drive_types[cdrom_get_type(c)].bus_type != cdrom[c].bus_type))
cdrom[c].bus_type = cdrom_drive_types[cdrom_get_type(c)].bus_type;
2022-07-21 21:44:55 -04:00
sprintf(tmp2, "%u, %s", cdrom[c].sound_on,
hdd_bus_to_string(cdrom[c].bus_type, 1));
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "cdrom_%02i_mke_channel", c + 1);
if (cdrom[c].bus_type != CDROM_BUS_MKE)
ini_section_delete_var(cat, temp);
else {
ini_section_set_int(cat, temp, cdrom[c].mke_channel);
}
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
if (cdrom[c].bus_type != CDROM_BUS_ATAPI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%01u", cdrom[c].ide_channel >> 1,
cdrom[c].ide_channel & 1);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
if (cdrom[c].bus_type != CDROM_BUS_SCSI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%02u", cdrom[c].scsi_device_id >> 4,
cdrom[c].scsi_device_id & 15);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "cdrom_%02i_image_path", c + 1);
if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else {
path_normalize(cdrom[c].image_path);
if (!strnicmp(cdrom[c].image_path, usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cdrom[c].image_path[strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cdrom[c].image_path);
2022-07-21 21:44:55 -04:00
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else {
path_normalize(cdrom[c].image_history[i]);
if (!strnicmp(cdrom[c].image_history[i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cdrom[c].image_history[i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cdrom[c].image_history[i]);
}
}
}
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
/* Save "Other Removable Devices" section. */
static void
save_other_removable_devices(void)
{
2022-09-10 13:32:46 +02:00
ini_section_t cat = ini_find_or_create_section(config, "Other removable devices");
2023-05-11 03:02:36 -04:00
char temp[512];
char tmp2[512];
2022-09-18 17:11:43 -04:00
int c;
2022-07-21 21:44:55 -04:00
for (c = 0; c < RDISK_NUM; c++) {
sprintf(temp, "rdisk_%02i_parameters", c + 1);
if (rdisk_drives[c].bus_type == 0) {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
} else {
sprintf(tmp2, "%u, %s", rdisk_drives[c].type,
hdd_bus_to_string(rdisk_drives[c].bus_type, 1));
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "rdisk_%02i_ide_channel", c + 1);
if (rdisk_drives[c].bus_type != RDISK_BUS_ATAPI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%01u", rdisk_drives[c].ide_channel >> 1,
rdisk_drives[c].ide_channel & 1);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "rdisk_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
sprintf(temp, "rdisk_%02i_writeprot", c + 1);
ini_section_delete_var(cat, temp);
2025-07-21 01:20:54 +06:00
sprintf(temp, "rdisk_%02i_scsi_location", c + 1);
if (rdisk_drives[c].bus_type != RDISK_BUS_SCSI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%02u", rdisk_drives[c].scsi_device_id >> 4,
rdisk_drives[c].scsi_device_id & 15);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "rdisk_%02i_image_path", c + 1);
if ((rdisk_drives[c].bus_type == 0) || (strlen(rdisk_drives[c].image_path) == 0))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
save_image_file(cat, temp, rdisk_drives[c].image_path);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "rdisk_%02i_image_history_%02i", c + 1, i + 1);
if ((rdisk_drives[c].image_history[i] == 0) || strlen(rdisk_drives[c].image_history[i]) == 0)
ini_section_delete_var(cat, temp);
else
save_image_file(cat, temp, rdisk_drives[c].image_history[i]);
}
2018-01-26 22:17:09 +01:00
}
2022-07-21 21:44:55 -04:00
for (c = 0; c < MO_NUM; c++) {
sprintf(temp, "mo_%02i_parameters", c + 1);
if (mo_drives[c].bus_type == 0) {
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
} else {
sprintf(tmp2, "%u, %s", mo_drives[c].type,
hdd_bus_to_string(mo_drives[c].bus_type, 1));
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "mo_%02i_ide_channel", c + 1);
if (mo_drives[c].bus_type != MO_BUS_ATAPI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%01u", mo_drives[c].ide_channel >> 1,
mo_drives[c].ide_channel & 1);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "mo_%02i_scsi_id", c + 1);
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
2025-07-21 01:20:54 +06:00
sprintf(temp, "mo_%02i_writeprot", c + 1);
ini_section_delete_var(cat, temp);
2025-07-21 01:20:54 +06:00
2022-07-21 21:44:55 -04:00
sprintf(temp, "mo_%02i_scsi_location", c + 1);
if (mo_drives[c].bus_type != MO_BUS_SCSI)
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
2022-07-21 21:44:55 -04:00
else {
sprintf(tmp2, "%01u:%02u", mo_drives[c].scsi_device_id >> 4,
mo_drives[c].scsi_device_id & 15);
2022-09-10 13:32:46 +02:00
ini_section_set_string(cat, temp, tmp2);
2022-07-21 21:44:55 -04:00
}
sprintf(temp, "mo_%02i_image_path", c + 1);
if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0))
2022-09-10 13:32:46 +02:00
ini_section_delete_var(cat, temp);
else
save_image_file(cat, temp, mo_drives[c].image_path);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
if ((mo_drives[c].image_history[i] == 0) || strlen(mo_drives[c].image_history[i]) == 0)
ini_section_delete_var(cat, temp);
else
save_image_file(cat, temp, mo_drives[c].image_history[i]);
}
}
2022-09-10 13:32:46 +02:00
ini_delete_section_if_empty(config, cat);
}
void
config_save(void)
{
save_general(); /* General */
2023-05-11 03:02:36 -04:00
for (uint8_t i = 0; i < MONITORS_NUM; i++)
save_monitor(i); /* Monitors */
2022-07-21 21:44:55 -04:00
save_machine(); /* Machine */
save_video(); /* Video */
save_input_devices(); /* Input devices */
save_sound(); /* Sound */
save_network(); /* Network */
save_ports(); /* Ports (COM & LPT) */
save_storage_controllers(); /* Storage controllers */
save_hard_disks(); /* Hard disks */
save_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */
save_other_removable_devices(); /* Other removable devices */
save_other_peripherals(); /* Other peripherals */
#ifndef USE_SDL_UI
2025-03-09 01:39:07 +06:00
save_gl3_shaders(); /* GL3 Shaders */
#endif
save_keybinds(); /* Key bindings */
2022-09-10 13:32:46 +02:00
ini_write(config, cfg_path);
}
2022-09-10 13:32:46 +02:00
ini_t
config_get_ini(void)
{
2022-09-10 13:32:46 +02:00
return config;
}