From 9b1e90331ffa9699fa763a4f2ec927908a4d3b77 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 22 Jul 2022 23:35:18 -0400 Subject: [PATCH] Beginnings of CONFIG_BIOS support ported from machine&kb --- src/device.c | 41 ++++++++++++++++++++++++-- src/machine/machine.c | 11 +++++-- src/qt/qt_deviceconfig.cpp | 38 ++++++++++++++++++++++++ src/win/win_devconf.c | 59 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 142 insertions(+), 7 deletions(-) diff --git a/src/device.c b/src/device.c index 501ae6b64..331305f2d 100644 --- a/src/device.c +++ b/src/device.c @@ -48,6 +48,8 @@ #include <86box/config.h> #include <86box/device.h> #include <86box/machine.h> +#include <86box/mem.h> +#include <86box/rom.h> #include <86box/sound.h> @@ -329,13 +331,46 @@ device_get_priv(const device_t *d) int device_available(const device_t *d) { + device_config_t *config; + device_config_bios_t *bios; + int bf, roms_present = 0; + int i = 0; + #ifdef RELEASE_BUILD if (d->flags & DEVICE_NOT_WORKING) return(0); #endif - if (d->available != NULL) - return(d->available()); + if (d != NULL) { + config = (device_config_t *) d->config; + if (config != NULL) { + while (config->type != -1) { + if (config->type == CONFIG_BIOS) { + bios = (device_config_bios_t *) config->bios; - return(1); + /* Go through the ROM's in the device configuration. */ + while (bios->files_no != 0) { + i = 0; + for (bf = 0; bf < bios->files_no; bf++) + i += !!rom_present((char *) bios->files[bf]); + if (i == bios->files_no) + roms_present++; + bios++; + } + + return(roms_present ? -1 : 0); + } + config++; + } + } + + /* No CONFIG_BIOS field present, use the classic available(). */ + if (d->available != NULL) + return(d->available()); + else + return(1); + } + + /* A NULL device is never available. */ + return(0); } diff --git a/src/machine/machine.c b/src/machine/machine.c index 00516d8fb..67819b247 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -145,12 +145,19 @@ int machine_available(int m) { int ret; + device_t *d = (device_t *) machine_getdevice(m); bios_only = 1; - ret = machine_init_ex(m); + + ret = device_available(d); + /* Do not check via machine_init_ex() if the device is not NULL and + it has a CONFIG_BIOS field. */ + if ((d == NULL) || (ret != -1)) + ret = machine_init_ex(m); bios_only = 0; - return ret; + + return !!ret; } diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 0b2047785..6ebc59b5d 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -31,6 +31,8 @@ extern "C" { #include <86box/config.h> #include <86box/device.h> #include <86box/midi_rtmidi.h> +#include <86box/mem.h> +#include <86box/rom.h> } #include "qt_filefield.hpp" @@ -51,6 +53,8 @@ DeviceConfig::~DeviceConfig() void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Settings* settings) { DeviceConfig dc(settings); dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); + int combo_to_struct[256]; + int c, d, p, q; device_context_t device_context; device_set_context(&device_context, device, instance); @@ -140,6 +144,33 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting cbox->setCurrentIndex(currentIndex); break; } + case CONFIG_BIOS: + { + auto* cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto* model = cbox->model(); + int currentIndex = -1; + char *selected; + selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + + c = q = 0; + for (auto* bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { + p = 0; + for (d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + int row = Models::AddEntry(model, bios->name, q); + if (!strcmp(selected, bios->internal_name)) { + currentIndex = row; + } + c++; + } + q++; + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_SPINNER: { int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); @@ -188,6 +219,13 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); break; } + case CONFIG_BIOS: + { + auto* cbox = dc.findChild(config->name); + int idx = cbox->currentData().toInt(); + config_set_string(device_context.name, const_cast(config->name), const_cast(config->bios[idx].internal_name)); + break; + } case CONFIG_HEX16: { auto* cbox = dc.findChild(config->name); diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 804762af6..01bd58d0d 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -25,6 +25,8 @@ #include <86box/config.h> #include <86box/device.h> #include <86box/plat.h> +#include <86box/mem.h> +#include <86box/rom.h> #include <86box/midi_rtmidi.h> #include <86box/ui.h> #include <86box/win.h> @@ -33,7 +35,8 @@ static device_context_t config_device; -static uint8_t deviceconfig_changed = 0; +static uint8_t deviceconfig_changed = 0; +static int combo_to_struct[256]; #if defined(__amd64__) || defined(__aarch64__) @@ -46,14 +49,16 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) HWND h; int val_int, id, c, d; + int p, q; #ifdef USE_RTMIDI int num; #endif int changed, cid; const device_config_t *config; const device_config_selection_t *selection; + const device_config_bios_t *bios; char s[512], file_filter[512]; - char *str; + char *str, *val_str; wchar_t ws[512], *wstr; LPTSTR lptsTemp; @@ -65,9 +70,11 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) config = config_device.dev->config; lptsTemp = (LPTSTR) malloc(512); + memset(combo_to_struct, 0, 256 * sizeof(int)); while (config->type != -1) { selection = config->selection; + bios = config->bios; h = GetDlgItem(hdlg, id); switch (config->type) { @@ -94,6 +101,30 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c++; } + id += 2; + break; + case CONFIG_BIOS: + val_str = config_get_string((char *) config_device.name, + (char *) config->name, (char *) config->default_string); + + c = 0; + q = 0; + while (bios && bios->name && bios->name[0]) { + mbstowcs(lptsTemp, bios->name, strlen(bios->name) + 1); + p = 0; + for (d = 0; d < bios->files_no; d++) + p += !!rom_present((char *) bios->files[d]); + if (p == bios->files_no) { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + if (!strcmp(val_str, bios->internal_name)) + SendMessage(h, CB_SETCURSEL, c, 0); + combo_to_struct[c] = q; + c++; + } + q++; + bios++; + } + id += 2; break; #ifdef USE_RTMIDI @@ -188,6 +219,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (cid == IDOK) { id = IDC_CONFIG_BASE; config = config_device.dev->config; + bios = config->bios; changed = 0; char s[512]; @@ -217,6 +249,20 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (val_int != selection->value) changed = 1; + id += 2; + break; + case CONFIG_BIOS: + val_str = config_get_string((char *) config_device.name, + (char *) config->name, (char *) config->default_string); + + c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + for (; c > 0; c--) + bios++; + + if (strcmp(val_str, bios->internal_name)) + changed = 1; + id += 2; break; case CONFIG_MIDI_OUT: @@ -327,6 +373,14 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) selection++; config_set_int((char *) config_device.name, (char *) config->name, selection->value); + id += 2; + break; + case CONFIG_BIOS: + c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; + for (; c > 0; c--) + bios++; + config_set_string((char *) config_device.name, (char *) config->name, (char *) bios->internal_name); + id += 2; break; case CONFIG_MIDI_OUT: @@ -396,6 +450,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case CONFIG_SELECTION: case CONFIG_HEX16: case CONFIG_HEX20: + case CONFIG_BIOS: case CONFIG_MIDI_OUT: case CONFIG_MIDI_IN: case CONFIG_SPINNER: