diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index fdde472515..20977f48b1 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -2965,7 +2965,7 @@ image_close(void *local) free(img); if (temp_file[0] != 0x00) { - remove(temp_file); + remove(nvr_path(temp_file)); temp_file[0] = 0x00; } } diff --git a/src/chipset/headland.c b/src/chipset/headland.c index 4807661036..1c122e1267 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -220,9 +220,10 @@ memmap_state_default(headland_t *dev, uint8_t ht_romcs) mem_mapping_disable(&dev->mid_mapping); if (ht_romcs) - mem_set_mem_state(0x0e0000, 0x20000, MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state(0x0e0000, 0x10000, MEM_READ_ROMCS | MEM_WRITE_ROMCS); else - mem_set_mem_state(0x0e0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x0e0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_ROMCS | MEM_WRITE_ROMCS); mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_ROMCS | MEM_WRITE_ROMCS); mem_mapping_disable(&dev->shadow_mapping[0]); diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index ed7c269b01..132754ac77 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -28,6 +28,7 @@ #include <86box/device.h> #include <86box/mem.h> #include <86box/port_92.h> +#include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> #include <86box/chipset.h> @@ -176,6 +177,9 @@ opti499_write(uint16_t addr, uint8_t val, void *priv) break; case 0x22: + mem_a20_chipset = (val & 0x02); + mem_a20_recalc(); + fallthrough; case 0x23: case 0x26: case 0x2d: diff --git a/src/config.c b/src/config.c index 52eb05daeb..06049713ce 100644 --- a/src/config.c +++ b/src/config.c @@ -27,6 +27,11 @@ * -DANSI_CFG for use on these systems. */ +#ifdef _WIN32 +# include +#else +# include +#endif #include #ifdef ENABLE_CONFIG_LOG #include @@ -886,6 +891,25 @@ load_network(void) } else strcpy(nc->host_dev_name, "none"); + if (nc->net_type == NET_TYPE_SLIRP) { + sprintf(temp, "net_%02i_addr", c + 1); + p = ini_section_get_string(cat, temp, ""); + if (p && *p) { + struct in_addr addr; + if (inet_pton(AF_INET, p, &addr)) { + uint8_t *bytes = (uint8_t *)&addr.s_addr; + bytes[3] = 0; + sprintf(nc->slirp_net, "%d.%d.%d.0", bytes[0], bytes[1], bytes[2]); + } else { + nc->slirp_net[0] = '\0'; + } + } else { + nc->slirp_net[0] = '\0'; + } + } else { + nc->slirp_net[0] = '\0'; + } + sprintf(temp, "net_%02i_switch_group", c + 1); nc->switch_group = ini_section_get_int(cat, temp, NET_SWITCH_GRP_MIN); if (nc->switch_group < NET_SWITCH_GRP_MIN) @@ -1458,7 +1482,7 @@ load_floppy_and_cdrom_drives(void) int c; int d; int count = cdrom_get_type_count(); - + #ifndef DISABLE_FDD_AUDIO fdd_audio_load_profiles(); #endif @@ -1532,7 +1556,7 @@ load_floppy_and_cdrom_drives(void) fdd_set_audio_profile(c, d); #else fdd_set_audio_profile(c, 0); -#endif +#endif for (int i = 0; i < MAX_PREV_IMAGES; i++) { fdd_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); @@ -2987,6 +3011,14 @@ save_network(void) else ini_section_set_int(cat, temp, nc->link_state); + if (nc->net_type == NET_TYPE_SLIRP && nc->slirp_net[0] != '\0') { + sprintf(temp, "net_%02i_addr", c + 1); + ini_section_set_string(cat, temp, nc->slirp_net); + } else { + sprintf(temp, "net_%02i_addr", c + 1); + ini_section_delete_var(cat, temp); + } + sprintf(temp, "net_%02i_switch_group", c + 1); if (nc->switch_group == NET_SWITCH_GRP_MIN) ini_section_delete_var(cat, temp); diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 56548766ab..8b955c315a 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -2610,8 +2610,8 @@ ide_callback(void *priv) err = ABRT_ERR; else { /* Only accept after RESET or DIAG. */ - if (ide->params_specified) { - ide->cfg_spt = ide->tf->secount; + if (!ide->params_specified) { + ide->cfg_spt = (ide->tf->secount == 0) ? 256 : ide->tf->secount; ide->cfg_hpc = ide->tf->head + 1; ide->params_specified = 1; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ea5d562576..8241836730 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -749,6 +749,9 @@ extern int machine_at_4gpv5_init(const machine_t *); /* Contaq 82C597 */ extern int machine_at_greenb_init(const machine_t *); +/* OPTi 499 */ +extern int machine_at_xenon_init(const machine_t *); + /* OPTi 895 */ #ifdef EMU_DEVICE_H extern const device_t j403tg_device; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 9051189a63..1fc95c047e 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -307,6 +307,7 @@ extern int read_type; extern int mem_a20_state; extern int mem_a20_alt; +extern int mem_a20_chipset; extern int mem_a20_key; extern uint8_t read_mem_b(uint32_t addr); diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 2c91a6d9f5..f3f1b1f8a9 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -99,6 +99,7 @@ typedef struct netcard_conf_t { uint32_t link_state; uint8_t switch_group; uint8_t promisc_mode; + char slirp_net[16]; char nrs_hostname[128]; } netcard_conf_t; diff --git a/src/include/86box/prt_papersizes.h b/src/include/86box/prt_papersizes.h index e468abb35b..f0c9e626ac 100644 --- a/src/include/86box/prt_papersizes.h +++ b/src/include/86box/prt_papersizes.h @@ -28,27 +28,27 @@ #define LEDGER_PAGE_HEIGHT 17.0 /* Standard A0 */ -#define A0_PAGE_WIDTH 33.125 -#define A0_PAGE_HEIGHT 46.75 +#define A0_PAGE_WIDTH 33.110236 +#define A0_PAGE_HEIGHT 46.811023 /* Standard A1 */ -#define A1_PAGE_WIDTH 23.375 -#define A1_PAGE_HEIGHT 33.125 +#define A1_PAGE_WIDTH 23.385826 +#define A1_PAGE_HEIGHT 33.110236 /* Standard A2 */ -#define A2_PAGE_WIDTH 16.5 -#define A2_PAGE_HEIGHT 23.375 +#define A2_PAGE_WIDTH 16.535433 +#define A2_PAGE_HEIGHT 23.385826 /* Standard A3 */ -#define A3_PAGE_WIDTH 11.75 -#define A3_PAGE_HEIGHT 16.5 +#define A3_PAGE_WIDTH 11.692913 +#define A3_PAGE_HEIGHT 16.535433 /* Standard A4 */ -#define A4_PAGE_WIDTH 8.25 -#define A4_PAGE_HEIGHT 11.75 +#define A4_PAGE_WIDTH 8.267716 +#define A4_PAGE_HEIGHT 11.692913 /* Standard B4 */ -#define B4_PAGE_WIDTH 9.875 -#define B4_PAGE_HEIGHT 13.875 +#define B4_PAGE_WIDTH 9.8425197 +#define B4_PAGE_HEIGHT 13.897637 #endif /*EMU_PLAT_FALLTHROUGH_H*/ diff --git a/src/machine/m_at_socket1.c b/src/machine/m_at_socket1.c index 7d16e13818..ac836e05f2 100644 --- a/src/machine/m_at_socket1.c +++ b/src/machine/m_at_socket1.c @@ -396,6 +396,8 @@ machine_at_tuliptc38_init(const machine_t *model) device_add(&ide_isa_device); device_add_params(&fdc37c6xx_device, (void *) (FDC37C651 | FDC37C6XX_IDE_PRI)); + video_reset(gfxcard[0]); + if (gfxcard[0] == VID_INTERNAL) { bios_load_aux_linear("roms/machines/tuliptc38/VBIOS.BIN", 0x000c0000, 32768, 0); diff --git a/src/machine/m_at_socket2.c b/src/machine/m_at_socket2.c index d8fdd79f12..5ec4039b2b 100644 --- a/src/machine/m_at_socket2.c +++ b/src/machine/m_at_socket2.c @@ -311,6 +311,8 @@ machine_at_dell466np_init(const machine_t *model) machine_at_common_init(model); device_add(&sis_85c461_device); + video_reset(gfxcard[0]); + if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); else { @@ -354,6 +356,8 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); + video_reset(gfxcard[0]); + if (gfxcard[0] != VID_INTERNAL) { for (uint16_t i = 0; i < 32768; i++) rom[i] = mem_readb_phys(0x000c0000 + i); diff --git a/src/machine/m_at_socket3.c b/src/machine/m_at_socket3.c index 008394505f..7c8c801f6e 100644 --- a/src/machine/m_at_socket3.c +++ b/src/machine/m_at_socket3.c @@ -166,6 +166,29 @@ machine_at_greenb_init(const machine_t *model) return ret; } +/* OPTi 499 */ +int +machine_at_xenon_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/xenon/addx-bios-7-71-i28f001.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti499_device); + device_add(&ide_vlb_device); + device_add_params(&fdc37c6xx_device, (void *) (FDC37C661 | FDC37C6XX_IDE_PRI)); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + device_add(&intel_flash_bxt_device); + + return ret; +} + /* OPTi 895 */ static const device_config_t j403tg_config[] = { // clang-format off @@ -467,6 +490,8 @@ machine_at_tg486g_init(const machine_t *model) device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + video_reset(gfxcard[0]); + if (gfxcard[0] != VID_INTERNAL) { for (uint16_t i = 0; i < 32768; i++) rom[i] = mem_readb_phys(0x000c0000 + i); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index bf13025ff7..c64e15af8b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8761,6 +8761,50 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has AMIKey F KBC firmware. */ + { + .name = "[OPTi 499] ADD-X Normerel Xenon", + .internal_name = "xenon", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_499, + .init = machine_at_xenon_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_AMI | 0x00004600, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Version 1.0 has an AMIKEY-2, version 2.0 has a VIA VT82C42N KBC. */ { .name = "[OPTi 895] Jetway J-403TG", @@ -18511,11 +18555,10 @@ const machine_t machines[] = { .block = CPU_BLOCK(CPU_CYRIX3S), .min_bus = 66666667, .max_bus = 83333333, - /* TODO: to find the actual voltage and multiplier bus speeds. */ - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 + .min_voltage = 2050, + .max_voltage = 3100, + .min_multi = 3.5, + .max_multi = 5.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, diff --git a/src/mem/mem.c b/src/mem/mem.c index 91fa277be9..c456c840a7 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -106,9 +106,10 @@ int cachesize = 256; uint32_t get_phys_virt; uint32_t get_phys_phys; -int mem_a20_key = 0; -int mem_a20_alt = 0; -int mem_a20_state = 0; +int mem_a20_key = 0; +int mem_a20_alt = 0; +int mem_a20_chipset = 0; +int mem_a20_state = 0; int mmuflush = 0; @@ -3109,12 +3110,12 @@ mem_a20_recalc(void) if (!is286) { rammask = 0xfffff; flushmmucache(); - mem_a20_key = mem_a20_alt = mem_a20_state = 0; + mem_a20_key = mem_a20_alt = mem_a20_state = mem_a20_chipset = 0; return; } - state = mem_a20_key | mem_a20_alt; + state = mem_a20_key | mem_a20_alt | mem_a20_chipset; if (state && !mem_a20_state) { rammask = cpu_16bitbus ? 0xffffff : 0xffffffff; if (is6117) diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index c7243baacb..86c0896a72 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -43,6 +43,7 @@ #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include +# include #else # include #endif @@ -493,13 +494,30 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv slirp->pfd = calloc(1, slirp->pfd_size); #endif - /* Set the IP addresses to use. */ - struct in_addr net = { .s_addr = htonl(0x0a000000 | (slirp_card_num << 8)) }; /* 10.0.x.0 */ - struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */ - struct in_addr host = { .s_addr = htonl(0x0a000002 | (slirp_card_num << 8)) }; /* 10.0.x.2 */ - struct in_addr dhcp = { .s_addr = htonl(0x0a00000f | (slirp_card_num << 8)) }; /* 10.0.x.15 */ - struct in_addr dns = { .s_addr = htonl(0x0a000003 | (slirp_card_num << 8)) }; /* 10.0.x.3 */ - struct in_addr bind = { .s_addr = htonl(0x00000000) }; /* 0.0.0.0 */ + struct in_addr net; + struct in_addr host; + struct in_addr dhcp; + struct in_addr dns; + + /* Set the IP addresses to use. + Use a configured address if set, otherwise 10.0.x.0 */ + const char *slirp_net = net_cards_conf[card->card_num].slirp_net; + if (slirp_net[0] != '\0') { + struct in_addr addr; + inet_pton(AF_INET, slirp_net, &addr); + net.s_addr = htonl(ntohl(addr.s_addr) & 0xffffff00); + host.s_addr = htonl(ntohl(addr.s_addr) + 2); + dhcp.s_addr = htonl(ntohl(addr.s_addr) + 15); + dns.s_addr = htonl(ntohl(addr.s_addr) + 3); + } else { + net.s_addr = htonl(0x0a000000 | (slirp_card_num << 8)); /* 10.0.x.0 */ + host.s_addr = htonl(0x0a000002 | (slirp_card_num << 8)); /* 10.0.x.2 */ + dhcp.s_addr = htonl(0x0a00000f | (slirp_card_num << 8)); /* 10.0.x.15 */ + dns.s_addr = htonl(0x0a000003 | (slirp_card_num << 8)); /* 10.0.x.3 */ + } + + struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */ + struct in_addr bind = { .s_addr = htonl(0x00000000) }; /* 0.0.0.0 */ const SlirpConfig slirp_config = { #if SLIRP_CHECK_VERSION(4, 9, 0) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index e8ccb74f97..7164ec8356 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -265,6 +265,8 @@ typedef struct escp_t { uint8_t ctrl; PALETTE palcol; + + uint8_t auto_lf; } escp_t; /* Codepage table, needed for ESC t ( */ @@ -540,7 +542,7 @@ init_codepage(escp_t *dev, uint16_t num) static void reset_printer(escp_t *dev) { - dev->top_margin = dev->left_margin = 0.0; + dev->top_margin = dev->left_margin = 1.0 / 36.0; dev->right_margin = dev->page_width; switch (dev->paper_size) { case PAPER_A4: @@ -556,7 +558,7 @@ reset_printer(escp_t *dev) default: dev->page_height = LETTER_PAGE_HEIGHT; } - dev->bottom_margin = dev->page_height; + dev->bottom_margin = dev->page_height - 1.0 / 36.0; /* TODO: these should be configurable. */ dev->color = COLOR_BLACK; dev->curr_x = dev->curr_y = 0.0; @@ -1749,7 +1751,7 @@ process_char(escp_t *dev, uint8_t ch) case 0x0d: /* Carriage Return (CR) */ dev->curr_x = dev->left_margin; - if (!dev->autofeed) + if (!dev->autofeed && !dev->auto_lf) return 1; fallthrough; @@ -2214,7 +2216,9 @@ escp_init(const device_t *info) dev->page_height = LETTER_PAGE_HEIGHT; } - dev->dpi = dev->lang >= LANG_ESCP ? 360 : 240; + dev->auto_lf = device_get_config_int("auto_lf"); + + dev->dpi = dev->lang >= LANG_ESCP ? 360 : 240; /* Create 8-bit grayscale buffer for the page. */ dev->page = (psurface_t *) malloc(sizeof(psurface_t)); @@ -2328,6 +2332,17 @@ static const device_config_t lpt_prt_escp_config[] = { }, .bios = { { 0 } } }, + { + .name = "auto_lf", + .description = "Auto LF", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on diff --git a/src/qt/languages/el-GR.po b/src/qt/languages/el-GR.po index 6933075a56..1442183df9 100644 --- a/src/qt/languages/el-GR.po +++ b/src/qt/languages/el-GR.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-26 17:57+0000\n" +"PO-Revision-Date: 2026-02-04 18:32+0000\n" "Last-Translator: DimMan88 \n" "Language-Team: Greek \n" "Language: el-GR\n" @@ -61,7 +61,7 @@ msgid "Remember size && position" msgstr "Απομνήμευση μεγέθους && θέσης" msgid "Re&nderer" -msgstr "Re&nderer" +msgstr "&Απεικονιστής" msgid "&Qt (Software)" msgstr "&Qt (Software)" @@ -397,7 +397,7 @@ msgid "Enabled (UTC)" msgstr "Ενεργό (UTC)" msgid "Dynamic Recompiler" -msgstr "Dynamic Recompiler" +msgstr "Δυναμικός Αναμεταγλωττιστής" msgid "CPU frame size" msgstr "Μέγεθος πλαισίου CPU" @@ -619,7 +619,7 @@ msgid "Image Format:" msgstr "Τύπος Εικόνας:" msgid "Block Size:" -msgstr "Block Size:" +msgstr "Μέγεθος Block:" msgid "Floppy drives:" msgstr "Οδηγοί δισκέτας:" @@ -721,10 +721,10 @@ msgid "Turbo" msgstr "Turbo" msgid "On" -msgstr "On" +msgstr "Ενεργό" msgid "Off" -msgstr "Off" +msgstr "Ανενεργό" msgid "All images" msgstr "Όλες οι εικόνες" @@ -1080,7 +1080,7 @@ msgid "Cartridge %1: %2" msgstr "Κασέτα δεδομένων %1: %2" msgid "Car&tridge %1: %2" -msgstr "Car&tridge %1: %2" +msgstr "&Κασέτα δεδομένων %1: %2" msgid "Cartridge images" msgstr "Εικόνες κασέτας δεδομένων" @@ -1460,13 +1460,13 @@ msgid "HDX image" msgstr "Εικόνα HDX" msgid "Fixed-size VHD" -msgstr "Fixed-size VHD" +msgstr "Σταθερό-μέγεθος VHD" msgid "Dynamic-size VHD" -msgstr "Dynamic-size VHD" +msgstr "Δυναμικό-μέγεθος VHD" msgid "Differencing VHD" -msgstr "Differencing VHD" +msgstr "Διαφοροποίηση VHD" msgid "(N/A)" msgstr "(Μ/Δ)" @@ -1481,19 +1481,19 @@ msgid "HDX image (.hdx)" msgstr "Εικόνα HDX (.hdx)" msgid "Fixed-size VHD (.vhd)" -msgstr "Fixed-size VHD (.vhd)" +msgstr "Σταθερό-μέγεθος VHD (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "Dynamic-size VHD (.vhd)" +msgstr "Δυναμικό-μέγεθος VHD (.vhd)" msgid "Differencing VHD (.vhd)" -msgstr "Differencing VHD (.vhd)" +msgstr "Διαφοροποίηση VHD (.vhd)" msgid "Large blocks (2 MB)" -msgstr "Large blocks (2 MB)" +msgstr "Μεγάλα blocks (2 MB)" msgid "Small blocks (512 KB)" -msgstr "Small blocks (512 KB)" +msgstr "Μικρά blocks (512 KB)" msgid "VHD files" msgstr "Αρχεία VHD" @@ -2964,7 +2964,7 @@ msgid "version" msgstr "έκδοση" msgid "build" -msgstr "build" +msgstr "δομή" msgid "You are currently running version %1." msgstr "Τρέχετε την έκδοση %1." diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 4f34c34f55..af2e1e75e6 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1,7 +1,7 @@ msgid "" msgstr "" -"PO-Revision-Date: 2025-11-29 00:34+0000\n" -"Last-Translator: OBattler \n" +"PO-Revision-Date: 2026-02-06 05:57+0000\n" +"Last-Translator: Jeffrey Hope \n" "Language-Team: Spanish \n" "Language: es-ES\n" "MIME-Version: 1.0\n" @@ -1108,7 +1108,7 @@ msgid "Not running" msgstr "No en ejecución" msgid "Running" -msgstr "En ejeución" +msgstr "En ejecución" msgid "Paused" msgstr "En pausa" diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 8a12dd4412..fd4bc5610d 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -622,7 +622,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data()); ProgSettings::loadTranslators(&app); #ifdef Q_OS_WINDOWS - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(ProgSettings::getUIFont()); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f6195389c6..1133b26c09 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -2431,7 +2431,7 @@ MainWindow::changeEvent(QEvent *event) #ifdef Q_OS_WINDOWS if (event->type() == QEvent::LanguageChange) { auto size = this->centralWidget()->size(); - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(ProgSettings::getUIFont()); QApplication::processEvents(); main_window->centralWidget()->setFixedSize(size); QApplication::processEvents(); diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 62b63bbcc1..9be40c1cb7 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -28,6 +28,8 @@ #ifdef Q_OS_WINDOWS # include # include +# define WIN32_LEAN_AND_MEAN +# include #endif extern "C" { @@ -157,27 +159,67 @@ ProgSettings::~ProgSettings() delete ui; } +static QString sys_lang; + #ifdef Q_OS_WINDOWS -/* Return the standard font name on Windows, which is overridden per-language - to prevent CJK fonts with embedded bitmaps being chosen as a fallback. */ -QString -ProgSettings::getFontName(int langId) +/* Returns the standard UI font for Windows, which by default varies for different + languages. It can also be changed via external tools, if the user wants that. + + We use the message font here since that is what most Windows components and + other third-party programs use. */ +QFont +ProgSettings::getUIFont() { QString langCode = languageIdToCode(lang_id); - if (langCode == "ja-JP") { - /* Check for Windows 10 or later to choose the appropriate system font */ - if (QVersionNumber::fromString(QSysInfo::kernelVersion()).majorVersion() >= 10) - return "Yu Gothic UI"; - else - return "Meiryo UI"; - } else if (langCode == "ko-KR") - return "Malgun Gothic"; - else if (langCode == "zh-CN") - return "Microsoft YaHei"; - else if (langCode == "zh-TW") - return "Microsoft JhengHei"; - else - return "Segoe UI"; + + if ((langCode != sys_lang) && ((langCode == "ja-JP") || (langCode == "ko-KR") || + (langCode == "zh-CN") || (langCode == "zh-TW"))) { + /* + Work around Windows' inappropriate, ugly default fonts when using an East Asian + language when it is not also the system language. + */ + if (langCode == "ja-JP") { + /* Check for Windows 10 or later to choose the appropriate system font */ + if (QVersionNumber::fromString(QSysInfo::kernelVersion()).majorVersion() >= 10) + return QFont("Yu Gothic UI", 9); + else + return QFont("Meiryo UI", 9); + } else if (langCode == "ko-KR") + return QFont("Malgun Gothic", 9); + else if (langCode == "zh-CN") + return QFont("Microsoft YaHei", 9); + else if (langCode == "zh-TW") + return QFont("Microsoft JhengHei", 9); + } + + // Get the system (primary monitor) DPI. The font returned by + // SystemParametersInfo is scaled according to this and we need + // to get the font size in points to pass into QFont's constructor. + HDC hdc = GetDC(NULL); + int systemDpi = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + + // Get the font metrics. + NONCLIENTMETRICSW ncm = {}; + ncm.cbSize = sizeof(ncm); + // This should never happen, but just to be safe, return Segoe UI if + // SPI fails. + if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)) + { + return QFont("Segoe UI", 9); + } + + QString fontName = QString::fromWCharArray(ncm.lfMessageFont.lfFaceName); + // Windows' conversion from points to pixels goes as follows: + // + // -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72) + // + // (source: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfontw) + // + // Let's reverse that calculation to get the point size from the message font. + int fontSize = -MulDiv(ncm.lfMessageFont.lfHeight, 72, systemDpi); + + return QFont(fontName, fontSize); } #endif @@ -201,9 +243,42 @@ ProgSettings::languageIdToCode(int id) return languages[id].first; } +void +ProgSettings::getSysLang(QObject *parent) +{ + if (qtTranslator) { + QApplication::removeTranslator(qtTranslator); + qtTranslator = nullptr; + } + if (translator) { + QApplication::removeTranslator(translator); + translator = nullptr; + } + qtTranslator = new QTranslator(parent); + translator = new CustomTranslator(parent); + QString localetofilename = ""; + for (int i = 0; i < QLocale::system().uiLanguages().size(); i++) { + localetofilename = QLocale::system().uiLanguages()[i]; + if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/"))) { + qDebug() << "Translations loaded."; + QCoreApplication::installTranslator(translator); + /* First try qtbase */ + if (!loadQtTranslations(QLatin1String("qtbase_") + localetofilename.replace('-', '_'))) + /* If that fails, try legacy qt_* translations */ + if (!loadQtTranslations(QLatin1String("qt_") + localetofilename.replace('-', '_'))) + qDebug() << "Failed to find Qt translations!"; + if (QCoreApplication::installTranslator(qtTranslator)) + qDebug() << "Qt translations loaded."; + sys_lang = localetofilename; + break; + } + } +} + void ProgSettings::loadTranslators(QObject *parent) { + getSysLang(parent); if (qtTranslator) { QApplication::removeTranslator(qtTranslator); qtTranslator = nullptr; diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 2ada8c2bfa..cebfa8177b 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -15,10 +15,11 @@ class ProgSettings : public QDialog { explicit ProgSettings(QWidget *parent = nullptr); ~ProgSettings(); #ifdef Q_OS_WINDOWS - static QString getFontName(int langId); + static QFont getUIFont(); #endif static int languageCodeToId(QString langCode); static QString languageIdToCode(int id); + static void getSysLang(QObject *parent = nullptr); static void loadTranslators(QObject *parent = nullptr); static void reloadStrings(); class CustomTranslator : public QTranslator { diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp index 40d0fb1856..300e227e25 100644 --- a/src/qt/qt_vmmanager_details.cpp +++ b/src/qt/qt_vmmanager_details.cpp @@ -165,7 +165,7 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) connect(this, &VMManagerDetails::styleUpdated, portsSection, &VMManagerDetailSection::updateStyle); connect(this, &VMManagerDetails::styleUpdated, otherSection, &VMManagerDetailSection::updateStyle); - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(ProgSettings::getUIFont()); #endif sysconfig = new VMManagerSystem(); diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 17bd898bda..a520026533 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -269,7 +269,7 @@ VMManagerMainWindow::changeEvent(QEvent *event) { #ifdef Q_OS_WINDOWS if (event->type() == QEvent::LanguageChange) { - QApplication::setFont(QFont(ProgSettings::getFontName(lang_id), 9)); + QApplication::setFont(QFont(ProgSettings::getUIFont())); } #endif QWidget::changeEvent(event);