mirror of https://github.com/xemu-project/xemu.git
config: Migrate to genconfig system
This commit is contained in:
parent
30fa9e1df1
commit
d14cdbc7ba
|
@ -0,0 +1,68 @@
|
|||
general:
|
||||
updates:
|
||||
check:
|
||||
type: bool
|
||||
default: true
|
||||
misc:
|
||||
skip_boot_anim: bool
|
||||
user_token: string
|
||||
|
||||
input:
|
||||
bindings:
|
||||
port1: string
|
||||
port2: string
|
||||
port3: string
|
||||
port4: string
|
||||
|
||||
display:
|
||||
quality:
|
||||
surface_scale:
|
||||
type: integer
|
||||
default: 1
|
||||
window:
|
||||
last_width: integer
|
||||
last_height: integer
|
||||
ui:
|
||||
fit:
|
||||
type: enum
|
||||
values: [center, scale, scale_16_9, scale_4_3, stretch]
|
||||
default: scale
|
||||
scale:
|
||||
type: integer
|
||||
default: 1
|
||||
|
||||
audio:
|
||||
use_dsp: bool
|
||||
|
||||
net:
|
||||
enable: bool
|
||||
backend:
|
||||
type: enum
|
||||
values: [nat, udp, pcap]
|
||||
default: nat
|
||||
pcap:
|
||||
netif: string
|
||||
udp:
|
||||
bind_addr:
|
||||
type: string
|
||||
default: 0.0.0.0:9368
|
||||
remote_addr:
|
||||
type: string
|
||||
default: 1.2.3.4:9368
|
||||
|
||||
sys:
|
||||
mem_limit:
|
||||
type: enum
|
||||
values: ['64', '128']
|
||||
default: '64'
|
||||
files:
|
||||
bootrom_path: string
|
||||
flashrom_path: string
|
||||
eeprom_path: string
|
||||
hdd_path: string
|
||||
dvd_path: string
|
||||
|
||||
perf:
|
||||
hard_fpu:
|
||||
type: bool
|
||||
default: true
|
|
@ -1 +1 @@
|
|||
Subproject commit 218d283f65b96232518c252c792a9ff197aca995
|
||||
Subproject commit 8220e8748922ddd9bba4cbacd608601586c9a4bb
|
|
@ -2624,9 +2624,7 @@ void mcpx_apu_init(PCIBus *bus, int devfn, MemoryRegion *ram)
|
|||
/* Until DSP is more performant, a switch to decide whether or not we should
|
||||
* use the full audio pipeline or not.
|
||||
*/
|
||||
int use_dsp;
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_AUDIO_USE_DSP, &use_dsp);
|
||||
if (use_dsp) {
|
||||
if (g_config.audio.use_dsp) {
|
||||
d->mon = MCPX_APU_DEBUG_MON_GP_OR_EP;
|
||||
d->gp.realtime = true;
|
||||
d->ep.realtime = true;
|
||||
|
|
|
@ -3707,9 +3707,7 @@ void nv2a_set_surface_scale_factor(unsigned int scale)
|
|||
{
|
||||
NV2AState *d = g_nv2a;
|
||||
|
||||
xemu_settings_set_int(XEMU_SETTINGS_DISPLAY_RENDER_SCALE,
|
||||
scale < 1 ? 1 : scale);
|
||||
xemu_settings_save();
|
||||
g_config.display.quality.surface_scale = scale < 1 ? 1 : scale;
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
||||
|
@ -3750,8 +3748,7 @@ unsigned int nv2a_get_surface_scale_factor(void)
|
|||
|
||||
static void pgraph_reload_surface_scale_factor(NV2AState *d)
|
||||
{
|
||||
int factor;
|
||||
xemu_settings_get_int(XEMU_SETTINGS_DISPLAY_RENDER_SCALE, &factor);
|
||||
int factor = g_config.display.quality.surface_scale;
|
||||
d->pgraph.surface_scale_factor = factor < 1 ? 1 : factor;
|
||||
}
|
||||
|
||||
|
|
18
meson.build
18
meson.build
|
@ -837,6 +837,9 @@ if 'CONFIG_OPENGL' in config_host
|
|||
link_args: config_host['OPENGL_LIBS'].split())
|
||||
endif
|
||||
|
||||
tomlpp = declare_dependency(include_directories: 'tomlplusplus')
|
||||
genconfig = declare_dependency(include_directories: 'genconfig')
|
||||
|
||||
xemu_gtk = declare_dependency(compile_args: config_host['XEMU_GTK_CFLAGS'].split(),
|
||||
link_args: config_host['XEMU_GTK_LIBS'].split())
|
||||
|
||||
|
@ -2056,8 +2059,20 @@ qemu_version = custom_target('qemu-version.h',
|
|||
build_by_default: true,
|
||||
build_always_stale: true)
|
||||
|
||||
genconfig_cmd = [
|
||||
python, files('genconfig/gen_config.py'),
|
||||
meson.source_root() / 'config_spec.yml', 'xemu-config.h'
|
||||
]
|
||||
|
||||
xemu_config = custom_target('xemu-config.h',
|
||||
output: 'xemu-config.h',
|
||||
input: [ files('config_spec.yml') ],
|
||||
command: genconfig_cmd,
|
||||
depend_files: files('config_spec.yml'))
|
||||
|
||||
genh += qemu_version
|
||||
genh += xemu_version
|
||||
genh += xemu_config
|
||||
|
||||
hxdep = []
|
||||
hx_headers = [
|
||||
|
@ -2300,6 +2315,9 @@ specific_ss.add(files('xemu-xbe.c', 'xemu-version.c'))
|
|||
|
||||
common_ss.add(files('cpus-common.c'))
|
||||
|
||||
common_ss.add(tomlpp)
|
||||
common_ss.add(genconfig)
|
||||
|
||||
subdir('softmmu')
|
||||
|
||||
common_ss.add(capstone)
|
||||
|
|
37
softmmu/vl.c
37
softmmu/vl.c
|
@ -1970,9 +1970,7 @@ static void qemu_create_late_backends(void)
|
|||
net_init_clients(&error_fatal);
|
||||
|
||||
#ifdef XBOX
|
||||
int xemu_net_enabled;
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_NETWORK_ENABLED, &xemu_net_enabled);
|
||||
if (xemu_net_enabled) {
|
||||
if (g_config.net.enable) {
|
||||
xemu_net_enable();
|
||||
}
|
||||
#endif
|
||||
|
@ -2801,8 +2799,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
fake_argv[fake_argc++] = strdup("-machine");
|
||||
|
||||
char *bootrom_arg = NULL;
|
||||
const char *bootrom_path;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, &bootrom_path);
|
||||
const char *bootrom_path = g_config.sys.files.bootrom_path;
|
||||
|
||||
if (strlen(bootrom_path) > 0) {
|
||||
int bootrom_size = get_image_size(bootrom_path);
|
||||
|
@ -2828,12 +2825,9 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
}
|
||||
}
|
||||
|
||||
int short_animation;
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_SYSTEM_SHORTANIM, &short_animation);
|
||||
|
||||
fake_argv[fake_argc++] = g_strdup_printf("xbox%s%s%s",
|
||||
(bootrom_arg != NULL) ? bootrom_arg : "",
|
||||
short_animation ? ",short-animation=on" : "",
|
||||
g_config.general.misc.skip_boot_anim ? ",short-animation=on" : "",
|
||||
",kernel-irqchip=off"
|
||||
);
|
||||
|
||||
|
@ -2841,8 +2835,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
g_free(bootrom_arg);
|
||||
}
|
||||
|
||||
const char *eeprom_path;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, &eeprom_path);
|
||||
const char *eeprom_path = g_config.sys.files.eeprom_path;
|
||||
|
||||
// Sanity check EEPROM file
|
||||
if (strlen(eeprom_path) > 0) {
|
||||
|
@ -2875,8 +2868,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
if (strlen(eeprom_path) == 0) {
|
||||
eeprom_path = xemu_settings_get_default_eeprom_path();
|
||||
if (xbox_eeprom_generate(eeprom_path, XBOX_EEPROM_VERSION_R1)) {
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, eeprom_path);
|
||||
xemu_settings_save();
|
||||
xemu_settings_set_string(&g_config.sys.files.eeprom_path, eeprom_path);
|
||||
fake_argv[fake_argc++] = strdup("-device");
|
||||
char *escaped_eeprom_path = strdup_double_commas(eeprom_path);
|
||||
fake_argv[fake_argc++] = g_strdup_printf("smbus-storage,file=%s",
|
||||
|
@ -2889,29 +2881,26 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
}
|
||||
}
|
||||
|
||||
const char *flash_path;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, &flash_path);
|
||||
const char *flashrom_path = g_config.sys.files.flashrom_path;
|
||||
autostart = 0; // Do not auto-start the machine without a valid BIOS file
|
||||
if (first_boot) {
|
||||
// Don't display an error if this is the first boot. Give user a chance
|
||||
// to configure the path.
|
||||
} else if (xemu_check_file(flash_path)) {
|
||||
char *msg = g_strdup_printf("Failed to open flash file '%s'. Please check machine settings.", flash_path);
|
||||
} else if (xemu_check_file(flashrom_path)) {
|
||||
char *msg = g_strdup_printf("Failed to open flash file '%s'. Please check machine settings.", flashrom_path);
|
||||
xemu_queue_error_message(msg);
|
||||
g_free(msg);
|
||||
} else {
|
||||
fake_argv[fake_argc++] = strdup("-bios");
|
||||
fake_argv[fake_argc++] = strdup(flash_path);
|
||||
fake_argv[fake_argc++] = strdup(flashrom_path);
|
||||
autostart = 1;
|
||||
}
|
||||
|
||||
int mem;
|
||||
xemu_settings_get_int(XEMU_SETTINGS_SYSTEM_MEMORY, &mem);
|
||||
int mem = ((int)g_config.sys.mem_limit + 1) * 64;
|
||||
fake_argv[fake_argc++] = strdup("-m");
|
||||
fake_argv[fake_argc++] = g_strdup_printf("%d", mem);
|
||||
|
||||
const char *hdd_path;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_HDD_PATH, &hdd_path);
|
||||
const char *hdd_path = g_config.sys.files.hdd_path;
|
||||
if (strlen(hdd_path) > 0) {
|
||||
if (xemu_check_file(hdd_path)) {
|
||||
char *msg = g_strdup_printf("Failed to open hard disk image file '%s'. Please check machine settings.", hdd_path);
|
||||
|
@ -2927,9 +2916,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
|||
}
|
||||
}
|
||||
|
||||
const char *dvd_path = "";
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_DVD_PATH, &dvd_path);
|
||||
|
||||
const char *dvd_path = g_config.sys.files.dvd_path;
|
||||
// Allow overriding the dvd path from command line
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i] && strcmp(argv[i], "-dvd_path") == 0) {
|
||||
|
|
|
@ -9046,7 +9046,7 @@ void tcg_x86_init(void)
|
|||
offsetof(CPUX86State, fpstt), "fpstt");
|
||||
|
||||
#if defined(XBOX) && defined(__x86_64__)
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_SYSTEM_HARD_FPU, &g_use_hard_fpu);
|
||||
g_use_hard_fpu = g_config.perf.hard_fpu;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ xemu_ss.add(files(
|
|||
'xemu-input.c',
|
||||
'xemu-monitor.c',
|
||||
'xemu-net.c',
|
||||
'xemu-settings.c',
|
||||
'xemu-settings.cc',
|
||||
'xemu-shaders.c',
|
||||
'xemu-hud.cc',
|
||||
'xemu-reporting.cc',
|
||||
|
|
199
ui/xemu-hud.cc
199
ui/xemu-hud.cc
|
@ -632,15 +632,10 @@ private:
|
|||
bool dirty;
|
||||
bool pending_restart;
|
||||
|
||||
char flash_path[MAX_STRING_LEN];
|
||||
char flashrom_path[MAX_STRING_LEN];
|
||||
char bootrom_path[MAX_STRING_LEN];
|
||||
char hdd_path[MAX_STRING_LEN];
|
||||
char eeprom_path[MAX_STRING_LEN];
|
||||
int memory_idx;
|
||||
bool short_animation;
|
||||
#if defined(_WIN32)
|
||||
bool check_for_update;
|
||||
#endif
|
||||
|
||||
public:
|
||||
SettingsWindow()
|
||||
|
@ -649,12 +644,10 @@ public:
|
|||
dirty = false;
|
||||
pending_restart = false;
|
||||
|
||||
flash_path[0] = '\0';
|
||||
flashrom_path[0] = '\0';
|
||||
bootrom_path[0] = '\0';
|
||||
hdd_path[0] = '\0';
|
||||
eeprom_path[0] = '\0';
|
||||
memory_idx = 0;
|
||||
short_animation = false;
|
||||
}
|
||||
|
||||
~SettingsWindow()
|
||||
|
@ -663,57 +656,20 @@ public:
|
|||
|
||||
void Load()
|
||||
{
|
||||
const char *tmp;
|
||||
int tmp_int;
|
||||
size_t len;
|
||||
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, &tmp);
|
||||
len = strlen(tmp);
|
||||
assert(len < MAX_STRING_LEN);
|
||||
strncpy(flash_path, tmp, sizeof(flash_path));
|
||||
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, &tmp);
|
||||
len = strlen(tmp);
|
||||
assert(len < MAX_STRING_LEN);
|
||||
strncpy(bootrom_path, tmp, sizeof(bootrom_path));
|
||||
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_HDD_PATH, &tmp);
|
||||
len = strlen(tmp);
|
||||
assert(len < MAX_STRING_LEN);
|
||||
strncpy(hdd_path, tmp, sizeof(hdd_path));
|
||||
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, &tmp);
|
||||
len = strlen(tmp);
|
||||
assert(len < MAX_STRING_LEN);
|
||||
strncpy(eeprom_path, tmp, sizeof(eeprom_path));
|
||||
|
||||
xemu_settings_get_int(XEMU_SETTINGS_SYSTEM_MEMORY, &tmp_int);
|
||||
memory_idx = (tmp_int-64)/64;
|
||||
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_SYSTEM_SHORTANIM, &tmp_int);
|
||||
short_animation = !!tmp_int;
|
||||
|
||||
#if defined(_WIN32)
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_MISC_CHECK_FOR_UPDATE, &tmp_int);
|
||||
check_for_update = !!tmp_int;
|
||||
#endif
|
||||
|
||||
strncpy(flashrom_path, g_config.sys.files.flashrom_path, sizeof(flashrom_path)-1);
|
||||
strncpy(bootrom_path, g_config.sys.files.bootrom_path, sizeof(bootrom_path)-1);
|
||||
strncpy(hdd_path, g_config.sys.files.hdd_path, sizeof(hdd_path)-1);
|
||||
strncpy(eeprom_path, g_config.sys.files.eeprom_path, sizeof(eeprom_path)-1);
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void Save()
|
||||
{
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, flash_path);
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, bootrom_path);
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_HDD_PATH, hdd_path);
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, eeprom_path);
|
||||
xemu_settings_set_int(XEMU_SETTINGS_SYSTEM_MEMORY, 64+memory_idx*64);
|
||||
xemu_settings_set_bool(XEMU_SETTINGS_SYSTEM_SHORTANIM, short_animation);
|
||||
#if defined(_WIN32)
|
||||
xemu_settings_set_bool(XEMU_SETTINGS_MISC_CHECK_FOR_UPDATE, check_for_update);
|
||||
#endif
|
||||
xemu_settings_save();
|
||||
xemu_queue_notification("Settings saved! Restart to apply updates.");
|
||||
xemu_settings_set_string(&g_config.sys.files.flashrom_path, flashrom_path);
|
||||
xemu_settings_set_string(&g_config.sys.files.bootrom_path, bootrom_path);
|
||||
xemu_settings_set_string(&g_config.sys.files.hdd_path, hdd_path);
|
||||
xemu_settings_set_string(&g_config.sys.files.eeprom_path, eeprom_path);
|
||||
xemu_queue_notification("Settings saved. Restart to apply updates.");
|
||||
pending_restart = true;
|
||||
}
|
||||
|
||||
|
@ -759,7 +715,7 @@ public:
|
|||
ImGui::NextColumn();
|
||||
float picker_width = ImGui::GetColumnWidth()-120*g_ui_scale;
|
||||
ImGui::SetNextItemWidth(picker_width);
|
||||
FilePicker("###Flash", flash_path, sizeof(flash_path), rom_file_filters);
|
||||
FilePicker("###Flash", flashrom_path, sizeof(flashrom_path), rom_file_filters);
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Text("MCPX Boot ROM File");
|
||||
|
@ -783,24 +739,18 @@ public:
|
|||
ImGui::Text("System Memory");
|
||||
ImGui::NextColumn();
|
||||
ImGui::SetNextItemWidth(ImGui::GetColumnWidth()*0.5);
|
||||
if (ImGui::Combo("###mem", &memory_idx, "64 MiB\0" "128 MiB\0")) {
|
||||
dirty = true;
|
||||
}
|
||||
ImGui::Combo("###mem", &g_config.sys.mem_limit, "64 MiB\0" "128 MiB\0");
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Dummy(ImVec2(0,0));
|
||||
ImGui::NextColumn();
|
||||
if (ImGui::Checkbox("Skip startup animation", &short_animation)) {
|
||||
dirty = true;
|
||||
}
|
||||
ImGui::Checkbox("Skip startup animation", &g_config.general.misc.skip_boot_anim);
|
||||
ImGui::NextColumn();
|
||||
|
||||
#if defined(_WIN32)
|
||||
ImGui::Dummy(ImVec2(0,0));
|
||||
ImGui::NextColumn();
|
||||
if (ImGui::Checkbox("Check for updates on startup", &check_for_update)) {
|
||||
dirty = true;
|
||||
}
|
||||
ImGui::Checkbox("Check for updates on startup", &g_config.general.updates.check);
|
||||
ImGui::NextColumn();
|
||||
#endif
|
||||
|
||||
|
@ -943,14 +893,11 @@ class NetworkInterfaceManager
|
|||
public:
|
||||
std::vector<std::unique_ptr<NetworkInterface>> ifaces;
|
||||
NetworkInterface *current_iface;
|
||||
const char *current_iface_name;
|
||||
bool failed_to_load_lib;
|
||||
|
||||
NetworkInterfaceManager()
|
||||
{
|
||||
current_iface = NULL;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_PCAP_INTERFACE,
|
||||
¤t_iface_name);
|
||||
failed_to_load_lib = false;
|
||||
}
|
||||
|
||||
|
@ -987,7 +934,7 @@ public:
|
|||
#else
|
||||
ifaces.emplace_back(new NetworkInterface(iter));
|
||||
#endif
|
||||
if (!strcmp(current_iface_name, iter->name)) {
|
||||
if (!strcmp(g_config.net.pcap.netif, iter->name)) {
|
||||
current_iface = ifaces.back().get();
|
||||
}
|
||||
}
|
||||
|
@ -998,10 +945,8 @@ public:
|
|||
void select(NetworkInterface &iface)
|
||||
{
|
||||
current_iface = &iface;
|
||||
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_PCAP_INTERFACE,
|
||||
xemu_settings_set_string(&g_config.net.pcap.netif,
|
||||
iface.pcap_name.c_str());
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_PCAP_INTERFACE,
|
||||
¤t_iface_name);
|
||||
}
|
||||
|
||||
bool is_current(NetworkInterface &iface)
|
||||
|
@ -1015,7 +960,6 @@ class NetworkWindow
|
|||
{
|
||||
public:
|
||||
bool is_open;
|
||||
int backend;
|
||||
char remote_addr[64];
|
||||
char local_addr[64];
|
||||
std::unique_ptr<NetworkInterfaceManager> iface_mgr;
|
||||
|
@ -1040,12 +984,8 @@ public:
|
|||
}
|
||||
|
||||
if (ImGui::IsWindowAppearing()) {
|
||||
const char *tmp;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &tmp);
|
||||
strncpy(remote_addr, tmp, sizeof(remote_addr)-1);
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &tmp);
|
||||
strncpy(local_addr, tmp, sizeof(local_addr)-1);
|
||||
xemu_settings_get_enum(XEMU_SETTINGS_NETWORK_BACKEND, &backend);
|
||||
strncpy(remote_addr, g_config.net.udp.remote_addr, sizeof(remote_addr)-1);
|
||||
strncpy(local_addr, g_config.net.udp.bind_addr, sizeof(local_addr)-1);
|
||||
}
|
||||
|
||||
ImGuiInputTextFlags flg = 0;
|
||||
|
@ -1061,23 +1001,20 @@ public:
|
|||
ImGui::SameLine(); HelpMarker("The network backend which the emulated NIC interacts with");
|
||||
ImGui::NextColumn();
|
||||
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
|
||||
int temp_backend = backend; // Temporary to make backend combo read-only (FIXME: surely there's a nicer way)
|
||||
if (ImGui::Combo("##backend", is_enabled ? &temp_backend : &backend, "NAT\0UDP Tunnel\0Bridged Adapter\0") && !is_enabled) {
|
||||
xemu_settings_set_enum(XEMU_SETTINGS_NETWORK_BACKEND, backend);
|
||||
xemu_settings_save();
|
||||
}
|
||||
int temp_backend = g_config.net.backend; // Temporary to make backend combo read-only (FIXME: surely there's a nicer way)
|
||||
ImGui::Combo("##backend", is_enabled ? &temp_backend : &g_config.net.backend, "NAT\0UDP Tunnel\0Bridged Adapter\0");
|
||||
if (is_enabled) ImGui::PopStyleVar();
|
||||
ImGui::SameLine();
|
||||
if (backend == XEMU_NET_BACKEND_USER) {
|
||||
if (g_config.net.backend == CONFIG_NET_BACKEND_NAT) {
|
||||
HelpMarker("User-mode TCP/IP stack with network address translation");
|
||||
} else if (backend == XEMU_NET_BACKEND_SOCKET_UDP) {
|
||||
} else if (g_config.net.backend == CONFIG_NET_BACKEND_UDP) {
|
||||
HelpMarker("Tunnels link-layer traffic to a remote host via UDP");
|
||||
} else if (backend == XEMU_NET_BACKEND_PCAP) {
|
||||
} else if (g_config.net.backend == CONFIG_NET_BACKEND_PCAP) {
|
||||
HelpMarker("Bridges with a host network interface");
|
||||
}
|
||||
ImGui::NextColumn();
|
||||
|
||||
if (backend == XEMU_NET_BACKEND_SOCKET_UDP) {
|
||||
if (g_config.net.backend == CONFIG_NET_BACKEND_UDP) {
|
||||
ImGui::Text("Remote Host");
|
||||
ImGui::SameLine(); HelpMarker("The remote <IP address>:<Port> to forward packets to (e.g. 1.2.3.4:9368)");
|
||||
ImGui::NextColumn();
|
||||
|
@ -1096,7 +1033,7 @@ public:
|
|||
ImGui::InputText("###local_host", local_addr, sizeof(local_addr), flg);
|
||||
if (is_enabled) ImGui::PopStyleVar();
|
||||
ImGui::NextColumn();
|
||||
} else if (backend == XEMU_NET_BACKEND_PCAP) {
|
||||
} else if (g_config.net.backend == CONFIG_NET_BACKEND_PCAP) {
|
||||
static bool should_refresh = true;
|
||||
if (iface_mgr.get() == nullptr) {
|
||||
iface_mgr.reset(new NetworkInterfaceManager());
|
||||
|
@ -1128,7 +1065,7 @@ public:
|
|||
const char *selected_display_name = (
|
||||
iface_mgr->current_iface
|
||||
? iface_mgr->current_iface->friendlyname.c_str()
|
||||
: iface_mgr->current_iface_name
|
||||
: g_config.net.pcap.netif
|
||||
);
|
||||
if (is_enabled) ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f);
|
||||
if (ImGui::BeginCombo("###network_iface", selected_display_name)) {
|
||||
|
@ -1169,14 +1106,12 @@ public:
|
|||
ImGui::SetItemDefaultFocus();
|
||||
if (ImGui::Button(is_enabled ? "Disable" : "Enable", ImVec2(120*g_ui_scale, 0))) {
|
||||
if (!is_enabled) {
|
||||
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, remote_addr);
|
||||
xemu_settings_set_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, local_addr);
|
||||
xemu_settings_set_string(&g_config.net.udp.remote_addr, remote_addr);
|
||||
xemu_settings_set_string(&g_config.net.udp.bind_addr, local_addr);
|
||||
xemu_net_enable();
|
||||
} else {
|
||||
xemu_net_disable();
|
||||
}
|
||||
xemu_settings_set_bool(XEMU_SETTINGS_NETWORK_ENABLED, xemu_net_is_enabled());
|
||||
xemu_settings_save();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
@ -1290,10 +1225,7 @@ public:
|
|||
description[0] = '\x00';
|
||||
report.compat_comments = description;
|
||||
|
||||
const char *tmp;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_MISC_USER_TOKEN, &tmp);
|
||||
assert(strlen(tmp) < sizeof(token_buf));
|
||||
strncpy(token_buf, tmp, sizeof(token_buf));
|
||||
strncpy(token_buf, g_config.general.user_token, sizeof(token_buf)-1);
|
||||
report.token = token_buf;
|
||||
|
||||
dirty = true;
|
||||
|
@ -1411,12 +1343,8 @@ public:
|
|||
did_send = true;
|
||||
send_result = report.Send();
|
||||
if (send_result) {
|
||||
// Close window on success
|
||||
is_open = false;
|
||||
|
||||
// Save user token if it was used
|
||||
xemu_settings_set_string(XEMU_SETTINGS_MISC_USER_TOKEN, token_buf);
|
||||
xemu_settings_save();
|
||||
xemu_settings_set_string(&g_config.general.user_token, token_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1772,37 +1700,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void save_auto_update_selection(bool preference)
|
||||
{
|
||||
xemu_settings_set_bool(XEMU_SETTINGS_MISC_CHECK_FOR_UPDATE, preference);
|
||||
xemu_settings_save();
|
||||
should_prompt_auto_update_selection = false;
|
||||
}
|
||||
|
||||
void prompt_auto_update_selection()
|
||||
{
|
||||
ImGui::Text("Would you like xemu to check for updates on startup?");
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, ImGui::GetStyle().WindowPadding.y));
|
||||
ImGui::Separator();
|
||||
ImGui::Dummy(ImVec2(0.0f, ImGui::GetStyle().WindowPadding.y));
|
||||
|
||||
float w = (130)*g_ui_scale;
|
||||
float bw = w + (10)*g_ui_scale;
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth()-2*bw);
|
||||
|
||||
if (ImGui::Button("No", ImVec2(w, 0))) {
|
||||
save_auto_update_selection(false);
|
||||
is_open = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Yes", ImVec2(w, 0))) {
|
||||
save_auto_update_selection(true);
|
||||
check_for_updates_and_prompt_if_available();
|
||||
}
|
||||
}
|
||||
|
||||
void check_for_updates_and_prompt_if_available()
|
||||
{
|
||||
updater.check_for_update([this](){
|
||||
|
@ -1819,12 +1716,6 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (should_prompt_auto_update_selection) {
|
||||
prompt_auto_update_selection();
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::IsWindowAppearing() && !updater.is_update_available()) {
|
||||
updater.check_for_update();
|
||||
}
|
||||
|
@ -1993,23 +1884,19 @@ static bool is_shortcut_key_pressed(int scancode)
|
|||
|
||||
static void action_eject_disc(void)
|
||||
{
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_DVD_PATH, "");
|
||||
xemu_settings_save();
|
||||
xemu_settings_set_string(&g_config.sys.files.dvd_path, "");
|
||||
xemu_eject_disc();
|
||||
}
|
||||
|
||||
static void action_load_disc(void)
|
||||
{
|
||||
const char *iso_file_filters = ".iso Files\0*.iso\0All Files\0*.*\0";
|
||||
const char *current_disc_path;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_DVD_PATH, ¤t_disc_path);
|
||||
const char *new_disc_path = paused_file_open(NOC_FILE_DIALOG_OPEN, iso_file_filters, current_disc_path, NULL);
|
||||
const char *new_disc_path = paused_file_open(NOC_FILE_DIALOG_OPEN, iso_file_filters, g_config.sys.files.dvd_path, NULL);
|
||||
if (new_disc_path == NULL) {
|
||||
/* Cancelled */
|
||||
return;
|
||||
}
|
||||
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_DVD_PATH, new_disc_path);
|
||||
xemu_settings_save();
|
||||
xemu_settings_set_string(&g_config.sys.files.dvd_path, new_disc_path);
|
||||
xemu_load_disc(new_disc_path);
|
||||
}
|
||||
|
||||
|
@ -2120,8 +2007,7 @@ static void ShowMainMenu()
|
|||
if (ui_scale_combo > 1) ui_scale_combo = 1;
|
||||
if (ImGui::Combo("UI Scale", &ui_scale_combo, "1x\0" "2x\0")) {
|
||||
g_ui_scale = ui_scale_combo + 1;
|
||||
xemu_settings_set_int(XEMU_SETTINGS_DISPLAY_UI_SCALE, g_ui_scale);
|
||||
xemu_settings_save();
|
||||
g_config.display.ui.scale = g_ui_scale;
|
||||
g_trigger_style_update = true;
|
||||
}
|
||||
|
||||
|
@ -2131,9 +2017,7 @@ static void ShowMainMenu()
|
|||
}
|
||||
|
||||
if (ImGui::Combo(
|
||||
"Scaling Mode", &scaling_mode, "Center\0Scale\0Scale (Widescreen 16:9)\0Scale (4:3)\0Stretch\0")) {
|
||||
xemu_settings_set_enum(XEMU_SETTINGS_DISPLAY_SCALE, scaling_mode);
|
||||
xemu_settings_save();
|
||||
"Scaling Mode", &g_config.display.ui.fit, "Center\0Scale\0Scale (Widescreen 16:9)\0Scale (4:3)\0Stretch\0")) {
|
||||
}
|
||||
ImGui::SameLine(); HelpMarker("Controls how the rendered content should be scaled into the window");
|
||||
if (ImGui::MenuItem("Fullscreen", SHORTCUT_MENU_TEXT(Alt+F), xemu_is_fullscreen(), true)) {
|
||||
|
@ -2289,8 +2173,7 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
|
|||
|
||||
first_boot_window.is_open = xemu_settings_did_fail_to_load();
|
||||
|
||||
int ui_scale_int = 1;
|
||||
xemu_settings_get_int(XEMU_SETTINGS_DISPLAY_UI_SCALE, &ui_scale_int);
|
||||
int ui_scale_int = g_config.display.ui.scale;
|
||||
if (ui_scale_int < 1) ui_scale_int = 1;
|
||||
g_ui_scale = ui_scale_int;
|
||||
|
||||
|
@ -2299,13 +2182,7 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
|
|||
ImPlot::CreateContext();
|
||||
|
||||
#if defined(_WIN32)
|
||||
int should_check_for_update;
|
||||
xemu_settings_get_bool(XEMU_SETTINGS_MISC_CHECK_FOR_UPDATE, &should_check_for_update);
|
||||
if (should_check_for_update == -1) {
|
||||
update_window.should_prompt_auto_update_selection =
|
||||
update_window.is_open = !xemu_settings_did_fail_to_load();
|
||||
|
||||
} else if (should_check_for_update) {
|
||||
if (g_config.general.updates.check) {
|
||||
update_window.check_for_updates_and_prompt_if_available();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -87,11 +87,11 @@ ControllerStateList available_controllers =
|
|||
ControllerState *bound_controllers[4] = { NULL, NULL, NULL, NULL };
|
||||
int test_mode;
|
||||
|
||||
static const enum xemu_settings_keys port_index_to_settings_key_map[] = {
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_1_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID,
|
||||
static const char **port_index_to_settings_key_map[] = {
|
||||
&g_config.input.bindings.port1,
|
||||
&g_config.input.bindings.port2,
|
||||
&g_config.input.bindings.port3,
|
||||
&g_config.input.bindings.port4,
|
||||
};
|
||||
|
||||
void xemu_input_init(void)
|
||||
|
@ -141,9 +141,7 @@ int xemu_input_get_controller_default_bind_port(ControllerState *state, int star
|
|||
}
|
||||
|
||||
for (int i = start; i < 4; i++) {
|
||||
const char *this_port;
|
||||
xemu_settings_get_string(port_index_to_settings_key_map[i], &this_port);
|
||||
if (strcmp(guid, this_port) == 0) {
|
||||
if (strcmp(guid, *port_index_to_settings_key_map[i]) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +432,6 @@ void xemu_input_bind(int index, ControllerState *state, int save)
|
|||
}
|
||||
}
|
||||
xemu_settings_set_string(port_index_to_settings_key_map[index], guid_buf);
|
||||
xemu_settings_save();
|
||||
}
|
||||
|
||||
// Bind new controller
|
||||
|
|
|
@ -50,36 +50,28 @@ void xemu_net_enable(void)
|
|||
return;
|
||||
}
|
||||
|
||||
int backend;
|
||||
const char *local_addr, *remote_addr;
|
||||
xemu_settings_get_enum(XEMU_SETTINGS_NETWORK_BACKEND, &backend);
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_REMOTE_ADDR, &remote_addr);
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_LOCAL_ADDR, &local_addr);
|
||||
|
||||
// Create the netdev
|
||||
QDict *qdict;
|
||||
if (backend == XEMU_NET_BACKEND_USER) {
|
||||
if (g_config.net.backend == CONFIG_NET_BACKEND_NAT) {
|
||||
qdict = qdict_new();
|
||||
qdict_put_str(qdict, "id", id);
|
||||
qdict_put_str(qdict, "type", "user");
|
||||
} else if (backend == XEMU_NET_BACKEND_SOCKET_UDP) {
|
||||
} else if (g_config.net.backend == CONFIG_NET_BACKEND_UDP) {
|
||||
qdict = qdict_new();
|
||||
qdict_put_str(qdict, "id", id);
|
||||
qdict_put_str(qdict, "type", "socket");
|
||||
qdict_put_str(qdict, "udp", remote_addr);
|
||||
qdict_put_str(qdict, "localaddr", local_addr);
|
||||
} else if (backend == XEMU_NET_BACKEND_PCAP) {
|
||||
qdict_put_str(qdict, "udp", g_config.net.udp.remote_addr);
|
||||
qdict_put_str(qdict, "localaddr", g_config.net.udp.bind_addr);
|
||||
} else if (g_config.net.backend == CONFIG_NET_BACKEND_PCAP) {
|
||||
#if defined(_WIN32)
|
||||
if (pcap_load_library()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const char *iface;
|
||||
xemu_settings_get_string(XEMU_SETTINGS_NETWORK_PCAP_INTERFACE, &iface);
|
||||
qdict = qdict_new();
|
||||
qdict_put_str(qdict, "id", id);
|
||||
qdict_put_str(qdict, "type", "pcap");
|
||||
qdict_put_str(qdict, "ifname", iface);
|
||||
qdict_put_str(qdict, "ifname", g_config.net.pcap.netif);
|
||||
} else {
|
||||
// Unsupported backend type
|
||||
return;
|
||||
|
@ -111,6 +103,8 @@ void xemu_net_enable(void)
|
|||
xemu_queue_error_message(error_get_pretty(local_err));
|
||||
error_report_err(local_err);
|
||||
}
|
||||
|
||||
g_config.net.enable = true;
|
||||
}
|
||||
|
||||
static void remove_netdev(const char *name)
|
||||
|
@ -139,11 +133,13 @@ void xemu_net_disable(void)
|
|||
{
|
||||
remove_netdev(id);
|
||||
remove_netdev(id_hubport);
|
||||
g_config.net.enable = false;
|
||||
}
|
||||
|
||||
int xemu_net_is_enabled(void)
|
||||
{
|
||||
NetClientState *nc;
|
||||
nc = qemu_find_netdev(id);
|
||||
return (nc != NULL);
|
||||
g_config.net.enable = (nc != NULL);
|
||||
return g_config.net.enable;
|
||||
}
|
||||
|
|
|
@ -1,441 +0,0 @@
|
|||
/*
|
||||
* xemu Settings Management
|
||||
*
|
||||
* Copyright (C) 2020-2021 Matt Borgerson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <stdlib.h>
|
||||
#include <SDL_filesystem.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "xemu-settings.h"
|
||||
#include "inih/ini.c" // FIXME
|
||||
|
||||
enum config_types {
|
||||
CONFIG_TYPE_STRING,
|
||||
CONFIG_TYPE_INT,
|
||||
CONFIG_TYPE_BOOL,
|
||||
CONFIG_TYPE_ENUM,
|
||||
CONFIG_TYPE__MAX
|
||||
};
|
||||
|
||||
struct xemu_settings {
|
||||
// [system]
|
||||
char *flash_path;
|
||||
char *bootrom_path;
|
||||
char *hdd_path;
|
||||
char *dvd_path;
|
||||
char *eeprom_path;
|
||||
int memory;
|
||||
int short_animation; // Boolean
|
||||
int hard_fpu; // Boolean
|
||||
|
||||
// [audio]
|
||||
int use_dsp; // Boolean
|
||||
|
||||
// [display]
|
||||
int scale;
|
||||
int ui_scale;
|
||||
int render_scale;
|
||||
int window_width;
|
||||
int window_height;
|
||||
|
||||
// [input]
|
||||
char *controller_1_guid;
|
||||
char *controller_2_guid;
|
||||
char *controller_3_guid;
|
||||
char *controller_4_guid;
|
||||
|
||||
// [network]
|
||||
int net_enabled; // Boolean
|
||||
int net_backend;
|
||||
char *net_local_addr;
|
||||
char *net_remote_addr;
|
||||
char *net_pcap_iface;
|
||||
|
||||
// [misc]
|
||||
char *user_token;
|
||||
int check_for_update; // Boolean
|
||||
};
|
||||
|
||||
struct enum_str_map {
|
||||
int value;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
static const struct enum_str_map display_scale_map[DISPLAY_SCALE__COUNT+1] = {
|
||||
{ DISPLAY_SCALE_CENTER, "center" },
|
||||
{ DISPLAY_SCALE_SCALE, "scale" },
|
||||
{ DISPLAY_SCALE_WS169, "scale_ws169" },
|
||||
{ DISPLAY_SCALE_FS43, "scale_fs43" },
|
||||
{ DISPLAY_SCALE_STRETCH, "stretch" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
static const struct enum_str_map net_backend_map[XEMU_NET_BACKEND__COUNT+1] = {
|
||||
{ XEMU_NET_BACKEND_USER, "user" },
|
||||
{ XEMU_NET_BACKEND_SOCKET_UDP, "udp" },
|
||||
{ XEMU_NET_BACKEND_PCAP, "pcap" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
struct config_offset_table {
|
||||
enum config_types type;
|
||||
const char *section;
|
||||
const char *name;
|
||||
ptrdiff_t offset;
|
||||
union {
|
||||
const char *default_str;
|
||||
int default_int;
|
||||
int default_bool;
|
||||
};
|
||||
const struct enum_str_map *enum_map;
|
||||
} config_items[XEMU_SETTINGS__COUNT] = {
|
||||
// Please keep organized by section
|
||||
[XEMU_SETTINGS_SYSTEM_FLASH_PATH] = { CONFIG_TYPE_STRING, "system", "flash_path", offsetof(struct xemu_settings, flash_path), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_SYSTEM_BOOTROM_PATH] = { CONFIG_TYPE_STRING, "system", "bootrom_path", offsetof(struct xemu_settings, bootrom_path), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_SYSTEM_HDD_PATH] = { CONFIG_TYPE_STRING, "system", "hdd_path", offsetof(struct xemu_settings, hdd_path), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_SYSTEM_DVD_PATH] = { CONFIG_TYPE_STRING, "system", "dvd_path", offsetof(struct xemu_settings, dvd_path), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_SYSTEM_EEPROM_PATH] = { CONFIG_TYPE_STRING, "system", "eeprom_path", offsetof(struct xemu_settings, eeprom_path), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_SYSTEM_MEMORY] = { CONFIG_TYPE_INT, "system", "memory", offsetof(struct xemu_settings, memory), { .default_int = 64 } },
|
||||
[XEMU_SETTINGS_SYSTEM_SHORTANIM] = { CONFIG_TYPE_BOOL, "system", "shortanim", offsetof(struct xemu_settings, short_animation), { .default_bool = 0 } },
|
||||
[XEMU_SETTINGS_SYSTEM_HARD_FPU] = { CONFIG_TYPE_BOOL, "system", "hard_fpu", offsetof(struct xemu_settings, hard_fpu), { .default_bool = 1 } },
|
||||
|
||||
[XEMU_SETTINGS_AUDIO_USE_DSP] = { CONFIG_TYPE_BOOL, "audio", "use_dsp", offsetof(struct xemu_settings, use_dsp), { .default_bool = 0 } },
|
||||
|
||||
[XEMU_SETTINGS_DISPLAY_SCALE] = { CONFIG_TYPE_ENUM, "display", "scale", offsetof(struct xemu_settings, scale), { .default_int = DISPLAY_SCALE_SCALE }, display_scale_map },
|
||||
[XEMU_SETTINGS_DISPLAY_UI_SCALE] = { CONFIG_TYPE_INT, "display", "ui_scale", offsetof(struct xemu_settings, ui_scale), { .default_int = 1 } },
|
||||
[XEMU_SETTINGS_DISPLAY_RENDER_SCALE] = { CONFIG_TYPE_INT, "display", "render_scale", offsetof(struct xemu_settings, render_scale), { .default_int = 1 } },
|
||||
[XEMU_SETTINGS_DISPLAY_WINDOW_WIDTH] = { CONFIG_TYPE_INT, "display", "window_width", offsetof(struct xemu_settings, window_width), { .default_int = 1280 } },
|
||||
[XEMU_SETTINGS_DISPLAY_WINDOW_HEIGHT] = { CONFIG_TYPE_INT, "display", "window_height", offsetof(struct xemu_settings, window_height), { .default_int = 960 } },
|
||||
|
||||
[XEMU_SETTINGS_INPUT_CONTROLLER_1_GUID] = { CONFIG_TYPE_STRING, "input", "controller_1_guid", offsetof(struct xemu_settings, controller_1_guid), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID] = { CONFIG_TYPE_STRING, "input", "controller_2_guid", offsetof(struct xemu_settings, controller_2_guid), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID] = { CONFIG_TYPE_STRING, "input", "controller_3_guid", offsetof(struct xemu_settings, controller_3_guid), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID] = { CONFIG_TYPE_STRING, "input", "controller_4_guid", offsetof(struct xemu_settings, controller_4_guid), { .default_str = "" } },
|
||||
|
||||
[XEMU_SETTINGS_NETWORK_ENABLED] = { CONFIG_TYPE_BOOL, "network", "enabled", offsetof(struct xemu_settings, net_enabled), { .default_bool = 0 } },
|
||||
[XEMU_SETTINGS_NETWORK_BACKEND] = { CONFIG_TYPE_ENUM, "network", "backend", offsetof(struct xemu_settings, net_backend), { .default_int = XEMU_NET_BACKEND_USER }, net_backend_map },
|
||||
[XEMU_SETTINGS_NETWORK_LOCAL_ADDR] = { CONFIG_TYPE_STRING, "network", "local_addr", offsetof(struct xemu_settings, net_local_addr), { .default_str = "0.0.0.0:9368" } },
|
||||
[XEMU_SETTINGS_NETWORK_REMOTE_ADDR] = { CONFIG_TYPE_STRING, "network", "remote_addr", offsetof(struct xemu_settings, net_remote_addr), { .default_str = "1.2.3.4:9368" } },
|
||||
[XEMU_SETTINGS_NETWORK_PCAP_INTERFACE] = { CONFIG_TYPE_STRING, "network", "pcap_iface", offsetof(struct xemu_settings, net_pcap_iface), { .default_str = "" } },
|
||||
|
||||
[XEMU_SETTINGS_MISC_USER_TOKEN] = { CONFIG_TYPE_STRING, "misc", "user_token", offsetof(struct xemu_settings, user_token), { .default_str = "" } },
|
||||
[XEMU_SETTINGS_MISC_CHECK_FOR_UPDATE] = { CONFIG_TYPE_BOOL, "misc", "check_for_update", offsetof(struct xemu_settings, check_for_update), { .default_bool = -1 } },
|
||||
};
|
||||
|
||||
static const char *settings_path;
|
||||
static const char *filename = "xemu.ini";
|
||||
static struct xemu_settings *g_settings;
|
||||
static int settings_failed_to_load = 0;
|
||||
|
||||
static void *xemu_settings_get_field(enum xemu_settings_keys key, enum config_types type)
|
||||
{
|
||||
assert(key < XEMU_SETTINGS__COUNT);
|
||||
assert(config_items[key].type == type);
|
||||
return (void *)((char*)g_settings + config_items[key].offset);
|
||||
}
|
||||
|
||||
int xemu_settings_set_string(enum xemu_settings_keys key, const char *str)
|
||||
{
|
||||
char **field_str = (char **)xemu_settings_get_field(key, CONFIG_TYPE_STRING);
|
||||
if (*field_str) {
|
||||
free(*field_str);
|
||||
}
|
||||
*field_str = strdup(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_get_string(enum xemu_settings_keys key, const char **str)
|
||||
{
|
||||
*str = *(const char **)xemu_settings_get_field(key, CONFIG_TYPE_STRING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_set_int(enum xemu_settings_keys key, int val)
|
||||
{
|
||||
int *field_int = (int *)xemu_settings_get_field(key, CONFIG_TYPE_INT);
|
||||
*field_int = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_get_int(enum xemu_settings_keys key, int *val)
|
||||
{
|
||||
*val = *(int *)xemu_settings_get_field(key, CONFIG_TYPE_INT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_set_bool(enum xemu_settings_keys key, int val)
|
||||
{
|
||||
int *field_int = (int *)xemu_settings_get_field(key, CONFIG_TYPE_BOOL);
|
||||
*field_int = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_get_bool(enum xemu_settings_keys key, int *val)
|
||||
{
|
||||
*val = *(int *)xemu_settings_get_field(key, CONFIG_TYPE_BOOL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_set_enum(enum xemu_settings_keys key, int val)
|
||||
{
|
||||
int *field_int = (int *)xemu_settings_get_field(key, CONFIG_TYPE_ENUM);
|
||||
*field_int = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xemu_settings_get_enum(enum xemu_settings_keys key, int *val)
|
||||
{
|
||||
*val = *(int *)xemu_settings_get_field(key, CONFIG_TYPE_ENUM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool xemu_settings_detect_portable_mode(void)
|
||||
{
|
||||
bool val = false;
|
||||
char *portable_path = g_strdup_printf("%s%s", SDL_GetBasePath(), filename);
|
||||
FILE *tmpfile;
|
||||
if ((tmpfile = qemu_fopen(portable_path, "r"))) {
|
||||
fclose(tmpfile);
|
||||
val = true;
|
||||
}
|
||||
|
||||
free(portable_path);
|
||||
return val;
|
||||
}
|
||||
|
||||
void xemu_settings_set_path(const char *path)
|
||||
{
|
||||
assert(path != NULL);
|
||||
assert(settings_path == NULL);
|
||||
settings_path = path;
|
||||
fprintf(stderr, "%s: config path: %s\n", __func__, settings_path);
|
||||
}
|
||||
|
||||
const char *xemu_settings_get_path(void)
|
||||
{
|
||||
if (settings_path != NULL) {
|
||||
return settings_path;
|
||||
}
|
||||
|
||||
char *base = xemu_settings_detect_portable_mode()
|
||||
? SDL_GetBasePath()
|
||||
: SDL_GetPrefPath("xemu", "xemu");
|
||||
assert(base != NULL);
|
||||
settings_path = g_strdup_printf("%s%s", base, filename);
|
||||
SDL_free(base);
|
||||
fprintf(stderr, "%s: config path: %s\n", __func__, settings_path);
|
||||
return settings_path;
|
||||
}
|
||||
|
||||
const char *xemu_settings_get_default_eeprom_path(void)
|
||||
{
|
||||
static char *eeprom_path = NULL;
|
||||
if (eeprom_path != NULL) {
|
||||
return eeprom_path;
|
||||
}
|
||||
|
||||
char *base = xemu_settings_detect_portable_mode()
|
||||
? SDL_GetBasePath()
|
||||
: SDL_GetPrefPath("xemu", "xemu");
|
||||
assert(base != NULL);
|
||||
eeprom_path = g_strdup_printf("%s%s", base, "eeprom.bin");
|
||||
SDL_free(base);
|
||||
return eeprom_path;
|
||||
}
|
||||
|
||||
static int xemu_enum_str_to_int(const struct enum_str_map *map, const char *str, int *value)
|
||||
{
|
||||
for (int i = 0; map[i].str != NULL; i++) {
|
||||
if (strcmp(map[i].str, str) == 0) {
|
||||
*value = map[i].value;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int xemu_enum_int_to_str(const struct enum_str_map *map, int value, const char **str)
|
||||
{
|
||||
for (int i = 0; map[i].str != NULL; i++) {
|
||||
if (map[i].value == value) {
|
||||
*str = map[i].str;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static enum xemu_settings_keys xemu_key_from_name(const char *section, const char *name)
|
||||
{
|
||||
for (int i = 0; i < XEMU_SETTINGS__COUNT; i++) {
|
||||
if ((strcmp(section, config_items[i].section) == 0) &&
|
||||
(strcmp(name, config_items[i].name) == 0)) {
|
||||
return i; // Found
|
||||
}
|
||||
}
|
||||
|
||||
return XEMU_SETTINGS_INVALID;
|
||||
}
|
||||
|
||||
static int config_parse_callback(void *user, const char *section, const char *name, const char *value)
|
||||
{
|
||||
// struct xemu_settings *settings = (struct xemu_settings *)user;
|
||||
fprintf(stderr, "%s: [%s] %s = %s\n", __func__, section, name, value);
|
||||
|
||||
enum xemu_settings_keys key = xemu_key_from_name(section, name);
|
||||
|
||||
if (key == XEMU_SETTINGS_INVALID) {
|
||||
fprintf(stderr, "Ignoring unknown key %s.%s\n", section, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (config_items[key].type == CONFIG_TYPE_STRING) {
|
||||
xemu_settings_set_string(key, value);
|
||||
} else if (config_items[key].type == CONFIG_TYPE_INT) {
|
||||
int int_val;
|
||||
int converted = sscanf(value, "%d", &int_val);
|
||||
if (converted != 1) {
|
||||
fprintf(stderr, "Error parsing %s.%s as integer. Got '%s'\n", section, name, value);
|
||||
return 0;
|
||||
}
|
||||
xemu_settings_set_int(key, int_val);
|
||||
} else if (config_items[key].type == CONFIG_TYPE_BOOL) {
|
||||
int int_val;
|
||||
if (strcmp(value, "true") == 0) {
|
||||
int_val = 1;
|
||||
} else if (strcmp(value, "false") == 0) {
|
||||
int_val = 0;
|
||||
} else if (strcmp(value, "") == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, "Error parsing %s.%s as boolean. Got '%s'\n", section, name, value);
|
||||
return 0;
|
||||
}
|
||||
xemu_settings_set_bool(key, int_val);
|
||||
} else if (config_items[key].type == CONFIG_TYPE_ENUM) {
|
||||
int int_val;
|
||||
int status = xemu_enum_str_to_int(config_items[key].enum_map, value, &int_val);
|
||||
if (status != 0) {
|
||||
fprintf(stderr, "Error parsing %s.%s as enum. Got '%s'\n", section, name, value);
|
||||
return 0;
|
||||
}
|
||||
xemu_settings_set_enum(key, int_val);
|
||||
} else {
|
||||
// Unimplemented
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// Success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void xemu_settings_init_default(struct xemu_settings *settings)
|
||||
{
|
||||
memset(settings, 0, sizeof(struct xemu_settings));
|
||||
for (int i = 0; i < XEMU_SETTINGS__COUNT; i++) {
|
||||
if (config_items[i].type == CONFIG_TYPE_STRING) {
|
||||
xemu_settings_set_string(i, config_items[i].default_str);
|
||||
} else if (config_items[i].type == CONFIG_TYPE_INT) {
|
||||
xemu_settings_set_int(i, config_items[i].default_int);
|
||||
} else if (config_items[i].type == CONFIG_TYPE_BOOL) {
|
||||
xemu_settings_set_bool(i, config_items[i].default_bool);
|
||||
} else if (config_items[i].type == CONFIG_TYPE_ENUM) {
|
||||
xemu_settings_set_enum(i, config_items[i].default_int);
|
||||
} else {
|
||||
// Unimplemented
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int xemu_settings_did_fail_to_load(void)
|
||||
{
|
||||
return settings_failed_to_load;
|
||||
}
|
||||
|
||||
void xemu_settings_load(void)
|
||||
{
|
||||
// Should only call this once, at startup
|
||||
assert(g_settings == NULL);
|
||||
|
||||
g_settings = malloc(sizeof(struct xemu_settings));
|
||||
assert(g_settings != NULL);
|
||||
memset(g_settings, 0, sizeof(struct xemu_settings));
|
||||
xemu_settings_init_default(g_settings);
|
||||
|
||||
// Parse configuration file
|
||||
int status = ini_parse(xemu_settings_get_path(),
|
||||
config_parse_callback,
|
||||
g_settings);
|
||||
if (status < 0) {
|
||||
// fprintf(stderr, "Failed to load config! Using defaults\n");
|
||||
settings_failed_to_load = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void xemu_settings_save(void)
|
||||
{
|
||||
FILE *fd = qemu_fopen(xemu_settings_get_path(), "wb");
|
||||
assert(fd != NULL);
|
||||
|
||||
const char *last_section = "";
|
||||
for (int i = 0; i < XEMU_SETTINGS__COUNT; i++) {
|
||||
if (strcmp(last_section, config_items[i].section)) {
|
||||
fprintf(fd, "[%s]\n", config_items[i].section);
|
||||
last_section = config_items[i].section;
|
||||
}
|
||||
|
||||
fprintf(fd, "%s = ", config_items[i].name);
|
||||
if (config_items[i].type == CONFIG_TYPE_STRING) {
|
||||
const char *v;
|
||||
xemu_settings_get_string(i, &v);
|
||||
fprintf(fd, "%s\n", v);
|
||||
} else if (config_items[i].type == CONFIG_TYPE_INT) {
|
||||
int v;
|
||||
xemu_settings_get_int(i, &v);
|
||||
fprintf(fd, "%d\n", v);
|
||||
} else if (config_items[i].type == CONFIG_TYPE_BOOL) {
|
||||
int v;
|
||||
xemu_settings_get_bool(i, &v);
|
||||
if (v == 0 || v == 1) {
|
||||
fprintf(fd, "%s\n", !!(v) ? "true" : "false");
|
||||
} else {
|
||||
// Other values are considered unset
|
||||
}
|
||||
} else if (config_items[i].type == CONFIG_TYPE_ENUM) {
|
||||
int v;
|
||||
xemu_settings_get_enum(i, &v);
|
||||
const char *str = "";
|
||||
xemu_enum_int_to_str(config_items[i].enum_map, v, &str);
|
||||
fprintf(fd, "%s\n", str);
|
||||
} else {
|
||||
// Unimplemented
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* xemu Settings Management
|
||||
*
|
||||
* Copyright (C) 2020-2021 Matt Borgerson
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <stdlib.h>
|
||||
#include <SDL_filesystem.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <toml.hpp>
|
||||
#include <cnode.h>
|
||||
|
||||
#include "xemu-settings.h"
|
||||
#define DEFINE_CONFIG_TREE
|
||||
#include "xemu-config.h"
|
||||
|
||||
struct config g_config;
|
||||
static bool settings_failed_to_load = true;
|
||||
static const char *filename = "xemu.ini";
|
||||
static const char *settings_path;
|
||||
|
||||
static bool xemu_settings_detect_portable_mode(void)
|
||||
{
|
||||
bool val = false;
|
||||
char *portable_path = g_strdup_printf("%s%s", SDL_GetBasePath(), filename);
|
||||
FILE *tmpfile;
|
||||
if ((tmpfile = qemu_fopen(portable_path, "r"))) {
|
||||
fclose(tmpfile);
|
||||
val = true;
|
||||
}
|
||||
|
||||
free(portable_path);
|
||||
return val;
|
||||
}
|
||||
|
||||
void xemu_settings_set_path(const char *path)
|
||||
{
|
||||
assert(path != NULL);
|
||||
assert(settings_path == NULL);
|
||||
settings_path = path;
|
||||
fprintf(stderr, "%s: config path: %s\n", __func__, settings_path);
|
||||
}
|
||||
|
||||
const char *xemu_settings_get_path(void)
|
||||
{
|
||||
if (settings_path != NULL) {
|
||||
return settings_path;
|
||||
}
|
||||
|
||||
char *base = xemu_settings_detect_portable_mode()
|
||||
? SDL_GetBasePath()
|
||||
: SDL_GetPrefPath("xemu", "xemu");
|
||||
assert(base != NULL);
|
||||
settings_path = g_strdup_printf("%s%s", base, filename);
|
||||
SDL_free(base);
|
||||
fprintf(stderr, "%s: config path: %s\n", __func__, settings_path);
|
||||
return settings_path;
|
||||
}
|
||||
|
||||
const char *xemu_settings_get_default_eeprom_path(void)
|
||||
{
|
||||
static char *eeprom_path = NULL;
|
||||
if (eeprom_path != NULL) {
|
||||
return eeprom_path;
|
||||
}
|
||||
|
||||
char *base = xemu_settings_detect_portable_mode()
|
||||
? SDL_GetBasePath()
|
||||
: SDL_GetPrefPath("xemu", "xemu");
|
||||
assert(base != NULL);
|
||||
eeprom_path = g_strdup_printf("%s%s", base, "eeprom.bin");
|
||||
SDL_free(base);
|
||||
return eeprom_path;
|
||||
}
|
||||
|
||||
void xemu_settings_load(void)
|
||||
{
|
||||
FILE *fd;
|
||||
size_t file_size = 0;
|
||||
char *file_buf = NULL;
|
||||
const char *settings_path = xemu_settings_get_path();
|
||||
|
||||
fd = qemu_fopen(settings_path, "rb");
|
||||
if (!fd) {
|
||||
fprintf(stderr, "Failed to open settings path %s for reading\n", settings_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fseek(fd, 0, SEEK_END);
|
||||
file_size = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
file_buf = (char *)malloc(file_size + 1);
|
||||
if (fread(file_buf, file_size, 1, fd) != 1) {
|
||||
fprintf(stderr, "Failed to read settings\n");
|
||||
fclose(fd);
|
||||
fd = NULL;
|
||||
free(file_buf);
|
||||
file_buf = NULL;
|
||||
goto out;
|
||||
}
|
||||
file_buf[file_size] = '\x00';
|
||||
|
||||
try
|
||||
{
|
||||
auto tbl = toml::parse(file_buf);
|
||||
config_tree.update_from_table(tbl);
|
||||
settings_failed_to_load = false;
|
||||
}
|
||||
catch (const toml::parse_error& err)
|
||||
{
|
||||
std::cerr
|
||||
<< "Error parsing file '" << *err.source().path
|
||||
<< "':\n" << err.description()
|
||||
<< "\n (" << err.source().begin << ")\n";
|
||||
}
|
||||
|
||||
out:
|
||||
config_tree.store_to_struct(&g_config);
|
||||
}
|
||||
|
||||
bool xemu_settings_did_fail_to_load(void)
|
||||
{
|
||||
return settings_failed_to_load;
|
||||
}
|
||||
|
||||
void xemu_settings_save(void)
|
||||
{
|
||||
FILE *fd = qemu_fopen(xemu_settings_get_path(), "wb");
|
||||
assert(fd != NULL);
|
||||
config_tree.update_from_struct(&g_config);
|
||||
fprintf(fd, "%s", config_tree.generate_delta_toml().c_str());
|
||||
fclose(fd);
|
||||
}
|
|
@ -28,57 +28,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum xemu_settings_keys {
|
||||
XEMU_SETTINGS_SYSTEM_FLASH_PATH,
|
||||
XEMU_SETTINGS_SYSTEM_BOOTROM_PATH,
|
||||
XEMU_SETTINGS_SYSTEM_HDD_PATH,
|
||||
XEMU_SETTINGS_SYSTEM_EEPROM_PATH,
|
||||
XEMU_SETTINGS_SYSTEM_DVD_PATH,
|
||||
XEMU_SETTINGS_SYSTEM_MEMORY,
|
||||
XEMU_SETTINGS_SYSTEM_SHORTANIM,
|
||||
XEMU_SETTINGS_SYSTEM_HARD_FPU,
|
||||
XEMU_SETTINGS_AUDIO_USE_DSP,
|
||||
XEMU_SETTINGS_DISPLAY_SCALE,
|
||||
XEMU_SETTINGS_DISPLAY_UI_SCALE,
|
||||
XEMU_SETTINGS_DISPLAY_RENDER_SCALE,
|
||||
XEMU_SETTINGS_DISPLAY_WINDOW_WIDTH,
|
||||
XEMU_SETTINGS_DISPLAY_WINDOW_HEIGHT,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_1_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_2_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_3_GUID,
|
||||
XEMU_SETTINGS_INPUT_CONTROLLER_4_GUID,
|
||||
XEMU_SETTINGS_NETWORK_ENABLED,
|
||||
XEMU_SETTINGS_NETWORK_BACKEND,
|
||||
XEMU_SETTINGS_NETWORK_LOCAL_ADDR,
|
||||
XEMU_SETTINGS_NETWORK_REMOTE_ADDR,
|
||||
XEMU_SETTINGS_NETWORK_PCAP_INTERFACE,
|
||||
XEMU_SETTINGS_MISC_USER_TOKEN,
|
||||
XEMU_SETTINGS_MISC_CHECK_FOR_UPDATE,
|
||||
XEMU_SETTINGS__COUNT,
|
||||
XEMU_SETTINGS_INVALID = -1
|
||||
};
|
||||
#include "xemu-config.h"
|
||||
|
||||
enum DISPLAY_SCALE
|
||||
{
|
||||
DISPLAY_SCALE_CENTER,
|
||||
DISPLAY_SCALE_SCALE,
|
||||
DISPLAY_SCALE_WS169,
|
||||
DISPLAY_SCALE_FS43,
|
||||
DISPLAY_SCALE_STRETCH,
|
||||
DISPLAY_SCALE__COUNT,
|
||||
DISPLAY_SCALE_INVALID = -1
|
||||
};
|
||||
|
||||
enum xemu_net_backend {
|
||||
XEMU_NET_BACKEND_USER,
|
||||
XEMU_NET_BACKEND_SOCKET_UDP,
|
||||
XEMU_NET_BACKEND_PCAP,
|
||||
XEMU_NET_BACKEND__COUNT,
|
||||
XEMU_NET_BACKEND_INVALID = -1
|
||||
};
|
||||
extern struct config g_config;
|
||||
|
||||
// Determine whether settings were loaded or not
|
||||
int xemu_settings_did_fail_to_load(void);
|
||||
bool xemu_settings_did_fail_to_load(void);
|
||||
|
||||
// Override the default config file paths
|
||||
void xemu_settings_set_path(const char *path);
|
||||
|
@ -95,15 +50,14 @@ void xemu_settings_load(void);
|
|||
// Save config file to disk
|
||||
void xemu_settings_save(void);
|
||||
|
||||
// Config item setters/getters
|
||||
int xemu_settings_set_string(enum xemu_settings_keys key, const char *str);
|
||||
int xemu_settings_get_string(enum xemu_settings_keys key, const char **str);
|
||||
int xemu_settings_set_int(enum xemu_settings_keys key, int val);
|
||||
int xemu_settings_get_int(enum xemu_settings_keys key, int *val);
|
||||
int xemu_settings_set_bool(enum xemu_settings_keys key, int val);
|
||||
int xemu_settings_get_bool(enum xemu_settings_keys key, int *val);
|
||||
int xemu_settings_set_enum(enum xemu_settings_keys key, int val);
|
||||
int xemu_settings_get_enum(enum xemu_settings_keys key, int *val);
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline void xemu_settings_set_string(const char **str, const char *new_str)
|
||||
{
|
||||
free((char*)*str);
|
||||
*str = strdup(new_str);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
20
ui/xemu.c
20
ui/xemu.c
|
@ -108,7 +108,6 @@ static SDL_Cursor *guest_sprite;
|
|||
static Notifier mouse_mode_notifier;
|
||||
static SDL_Window *m_window;
|
||||
static SDL_GLContext m_context;
|
||||
int scaling_mode = 1;
|
||||
struct decal_shader *blit;
|
||||
|
||||
static QemuSemaphore display_init_sem;
|
||||
|
@ -593,8 +592,8 @@ static void handle_windowevent(SDL_Event *ev)
|
|||
dpy_set_ui_info(scon->dcl.con, &info);
|
||||
|
||||
if (!gui_fullscreen) {
|
||||
xemu_settings_set_int(XEMU_SETTINGS_DISPLAY_WINDOW_WIDTH, ev->window.data1);
|
||||
xemu_settings_set_int(XEMU_SETTINGS_DISPLAY_WINDOW_HEIGHT, ev->window.data2);
|
||||
g_config.display.window.last_width = ev->window.data1;
|
||||
g_config.display.window.last_height = ev->window.data2;
|
||||
}
|
||||
}
|
||||
sdl2_redraw(scon);
|
||||
|
@ -860,9 +859,8 @@ static void sdl2_display_very_early_init(DisplayOptions *o)
|
|||
SDL_DisplayMode disp_mode;
|
||||
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(m_window), &disp_mode);
|
||||
|
||||
int win_w, win_h;
|
||||
xemu_settings_get_int(XEMU_SETTINGS_DISPLAY_WINDOW_WIDTH, &win_w);
|
||||
xemu_settings_get_int(XEMU_SETTINGS_DISPLAY_WINDOW_HEIGHT, &win_h);
|
||||
int win_w = g_config.display.window.last_width,
|
||||
win_h = g_config.display.window.last_height;
|
||||
|
||||
if (win_w > 0 && win_h > 0) {
|
||||
if (disp_mode.w >= win_w && disp_mode.h >= win_h) {
|
||||
|
@ -938,8 +936,6 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
|
|||
assert(o->type == DISPLAY_TYPE_XEMU);
|
||||
SDL_GL_MakeCurrent(m_window, m_context);
|
||||
|
||||
xemu_settings_get_enum(XEMU_SETTINGS_DISPLAY_SCALE, &scaling_mode);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
SDL_VERSION(&info.version);
|
||||
|
||||
|
@ -1177,20 +1173,20 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)
|
|||
|
||||
// Calculate scaling factors
|
||||
float scale[2];
|
||||
if (scaling_mode == DISPLAY_SCALE_STRETCH) {
|
||||
if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_STRETCH) {
|
||||
// Stretch to fit
|
||||
scale[0] = 1.0;
|
||||
scale[1] = 1.0;
|
||||
} else if (scaling_mode == DISPLAY_SCALE_CENTER) {
|
||||
} else if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_CENTER) {
|
||||
// Centered
|
||||
scale[0] = (float)tw/(float)ww;
|
||||
scale[1] = (float)th/(float)wh;
|
||||
} else {
|
||||
float t_ratio;
|
||||
if (scaling_mode == DISPLAY_SCALE_WS169) {
|
||||
if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_SCALE_16_9) {
|
||||
// Scale to fit window using a fixed 16:9 aspect ratio
|
||||
t_ratio = 16.0f/9.0f;
|
||||
} else if (scaling_mode == DISPLAY_SCALE_FS43) {
|
||||
} else if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_SCALE_4_3) {
|
||||
t_ratio = 4.0f/3.0f;
|
||||
} else {
|
||||
// Scale to fit, preserving framebuffer aspect ratio
|
||||
|
|
Loading…
Reference in New Issue