diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9e5521cf4..69ca14b4a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,6 +9,8 @@ Checklist * [ ] I have discussed this with core contributors already * [ ] This pull request requires changes to the ROM set * [ ] I have opened a roms pull request - https://github.com/86Box/roms/pull/changeme/ +* [ ] This pull request requires changes to the asset set + * [ ] I have opened an assets pull request - https://github.com/86Box/assets/pull/changeme/ References ========== diff --git a/src/86box.c b/src/86box.c index efa9e84bf..020cb6090 100644 --- a/src/86box.c +++ b/src/86box.c @@ -143,10 +143,12 @@ int confirm_exit_cmdl = 1; /* (O) do not ask for confirmation on quit if set to uint64_t unique_id = 0; uint64_t source_hwnd = 0; #endif -char rom_path[1024] = { '\0' }; /* (O) full path to ROMs */ -rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */ -char log_path[1024] = { '\0' }; /* (O) full path of logfile */ -char vm_name[1024] = { '\0' }; /* (O) display name of the VM */ +char rom_path[1024] = { '\0' }; /* (O) full path to ROMs */ +rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */ +char asset_path[1024] = { '\0' }; /* (O) full path to assets */ +rom_path_t asset_paths = { "", NULL }; /* (O) full paths to assets */ +char log_path[1024] = { '\0' }; /* (O) full path of logfile */ +char vm_name[1024] = { '\0' }; /* (O) display name of the VM */ int do_nothing = 0; int dump_missing = 0; int clear_cmos = 0; @@ -662,6 +664,7 @@ pc_show_usage(char *s) "\n%sUsage: 86box [options] [cfg-file]\n\n" "Valid options are:\n\n" "-? or --help\t\t\t- show this information\n" + "-A or --assetpath path\t\t- set 'path' to be asset path\n" #ifdef SHOW_EXTRA_PARAMS "-C or --config path\t\t- set 'path' to be config file\n" #endif @@ -732,6 +735,7 @@ pc_init(int argc, char *argv[]) { char *ppath = NULL; char *rpath = NULL; + char *apath = NULL; char *cfg = NULL; char *global = NULL; char *p; @@ -798,6 +802,7 @@ pc_init(int argc, char *argv[]) */ plat_getcwd(usr_path, sizeof(usr_path) - 1); plat_getcwd(rom_path, sizeof(rom_path) - 1); + plat_getcwd(asset_path, sizeof(asset_path) - 1); for (c = 1; c < argc; c++) { if (argv[c][0] != '-') @@ -851,6 +856,12 @@ usage: rpath = argv[++c]; rom_add_path(rpath); + } else if (!strcasecmp(argv[c], "--assetpath") || !strcasecmp(argv[c], "-A")) { + if ((c + 1) == argc) + goto usage; + + apath = argv[++c]; + asset_add_path(apath); } else if (!strcasecmp(argv[c], "--config") || !strcasecmp(argv[c], "-C")) { if ((c + 1) == argc || plat_dir_check(argv[c + 1])) goto usage; @@ -974,6 +985,7 @@ usage: path_slash(usr_path); path_slash(rom_path); + path_slash(asset_path); /* * If the user provided a path for files, use that @@ -1014,6 +1026,16 @@ usage: plat_init_rom_paths(); + // Add the VM-local asset path. + path_append_filename(temp, usr_path, "assets"); + asset_add_path(temp); + + // Add the standard ROM path in the same directory as the executable. + path_append_filename(temp, exe_path, "assets"); + asset_add_path(temp); + + plat_init_asset_paths(); + /* * If the user provided a path for ROMs, use that * instead of the current working directory. We do @@ -1044,6 +1066,36 @@ usage: } else rom_path[0] = '\0'; + /* + * If the user provided a path for ROMs, use that + * instead of the current working directory. We do + * make sure that if that was a relative path, we + * make it absolute. + */ + if (apath != NULL) { + if (!path_abs(apath)) { + /* + * This looks like a relative path. + * + * Add it to the current working directory + * to convert it (back) to an absolute path. + */ + strcat(asset_path, apath); + } else { + /* + * The user-provided path seems like an + * absolute path, so just use that. + */ + strcpy(asset_path, apath); + } + + /* If the specified path does not yet exist, + create it. */ + if (!plat_dir_check(asset_path)) + plat_dir_create(asset_path); + } else + asset_path[0] = '\0'; + /* Grab the name of the configuration file. */ if (cfg == NULL) cfg = CONFIG_FILE; @@ -1081,6 +1133,8 @@ usage: path_slash(usr_path); if (rom_path[0] != '\0') path_slash(rom_path); + if (asset_path[0] != '\0') + path_slash(asset_path); /* At this point, we can safely create the full path name. */ path_append_filename(cfg_path, usr_path, p); @@ -1182,6 +1236,10 @@ usage: pclog("# ROM path: %s\n", rom_path->path); } + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + pclog("# Asset path: %s\n", asset_path->path); + } + /* * We are about to read the configuration file, which MAY * put data into global variables (the hard- and floppy diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 09886d6f8..c1bf04618 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1312,14 +1312,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->step = 1; } else { fdc->st0 = 0x20 | (fdc->params[0] & 3); - if (fdc->flags & FDC_FLAG_PCJR) { - fdc->fintr = 1; - fdc->interrupt = -4; - } else { - timer_disable(&fdc->timer); - fdc->interrupt = -3; - fdc_callback(fdc); - } + fdc->fintr = 1; + fdc->interrupt = -4; break; } } else { @@ -1327,14 +1321,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) if ((fdc->params[1] - fdc->pcn[fdc->params[0] & 3]) == 0) { fdc_log("Failed seek\n"); fdc->st0 = 0x20 | (fdc->params[0] & 3); - if (fdc->flags & FDC_FLAG_PCJR) { - fdc->fintr = 1; - fdc->interrupt = -4; - } else { - timer_disable(&fdc->timer); - fdc->interrupt = -3; - fdc_callback(fdc); - } + /* Always use the PCjr code, so both 386BSD and 1B/V3 work. */ + fdc->fintr = 1; + fdc->interrupt = -4; break; } if (fdc->params[1] > fdc->pcn[fdc->params[0] & 3]) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 7835fe3a2..dcf7e4d53 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -147,6 +147,7 @@ extern void plat_get_global_data_dir(char *outbuf, size_t len); extern void plat_get_temp_dir(char *outbuf, uint8_t len); extern void plat_get_vmm_dir(char *outbuf, size_t len); extern void plat_init_rom_paths(void); +extern void plat_init_asset_paths(void); extern int plat_dir_check(char *path); extern int plat_file_check(const char *path); extern int plat_dir_create(char *path); diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index 6865277c6..0caee9e1f 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -42,6 +42,9 @@ typedef struct rom_path_t { } rom_path_t; extern rom_path_t rom_paths; +extern rom_path_t asset_paths; + +extern void asset_add_path(const char *path); extern void rom_add_path(const char *path); @@ -53,8 +56,14 @@ extern void rom_write(uint32_t addr, uint8_t val, void *priv); extern void rom_writew(uint32_t addr, uint16_t val, void *priv); extern void rom_writel(uint32_t addr, uint32_t val, void *priv); +extern void asset_get_full_path(char *dest, const char *fn); + extern void rom_get_full_path(char *dest, const char *fn); +extern FILE *asset_fopen(const char *fn, char *mode); +extern int asset_getfile(const char *fn, char *s, int size); +extern int asset_present(const char *fn); + extern FILE *rom_fopen(const char *fn, char *mode); extern int rom_getfile(const char *fn, char *s, int size); extern int rom_present(const char *fn); diff --git a/src/mem/rom.c b/src/mem/rom.c index cee00cb0f..6943b53d3 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -85,6 +85,36 @@ rom_add_path(const char *path) path_slash(rom_path->path); } +void +asset_add_path(const char *path) +{ + char cwd[1024] = { 0 }; + + rom_path_t *asset_path = &asset_paths; + + if (asset_paths.path[0] != '\0') { + // Iterate to the end of the list. + while (asset_path->next != NULL) { + asset_path = asset_path->next; + } + + // Allocate the new entry. + asset_path = asset_path->next = calloc(1, sizeof(rom_path_t)); + } + + // Save the path, turning it into absolute if needed. + if (!path_abs((char *) path)) { + plat_getcwd(cwd, sizeof(cwd)); + path_slash(cwd); + snprintf(asset_path->path, sizeof(asset_path->path), "%s%s", cwd, path); + } else { + snprintf(asset_path->path, sizeof(asset_path->path), "%s", path); + } + + // Ensure the path ends with a separator. + path_slash(asset_path->path); +} + static int rom_check(const char *fn) { @@ -129,6 +159,31 @@ rom_get_full_path(char *dest, const char *fn) } } +void +asset_get_full_path(char *dest, const char *fn) +{ + char temp[1024] = { 0 }; + + dest[0] = 0x00; + + if (!strncmp(fn, "assets/", 5)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 5); + + if (rom_check(temp)) { + strcpy(dest, temp); + return; + } + } + + return; + } else { + /* Absolute path */ + strcpy(dest, fn); + } +} + FILE * rom_fopen(const char *fn, char *mode) { @@ -154,6 +209,31 @@ rom_fopen(const char *fn, char *mode) } } +FILE * +asset_fopen(const char *fn, char *mode) +{ + char temp[1024]; + FILE *fp = NULL; + + if ((fn == NULL) || (mode == NULL)) + return NULL; + + if (!strncmp(fn, "assets/", 5)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 5); + + if ((fp = plat_fopen(temp, mode)) != NULL) + return fp; + } + + return fp; + } else { + /* Absolute path */ + return plat_fopen(fn, mode); + } +} + int rom_getfile(const char *fn, char *s, int size) { @@ -182,6 +262,34 @@ rom_getfile(const char *fn, char *s, int size) } } +int +asset_getfile(const char *fn, char *s, int size) +{ + char temp[1024]; + + if (!strncmp(fn, "assets/", 5)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 5); + + if (plat_file_check(temp)) { + strncpy(s, temp, size); + return 1; + } + } + + return 0; + } else { + /* Absolute path */ + if (plat_file_check(fn)) { + strncpy(s, fn, size); + return 1; + } + + return 0; + } +} + int rom_present(const char *fn) { @@ -206,6 +314,30 @@ rom_present(const char *fn) } } +int +asset_present(const char *fn) +{ + char temp[1024]; + + if (fn == NULL) + return 0; + + if (!strncmp(fn, "assets/", 5)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 5); + + if (plat_file_check(temp)) + return 1; + } + + return 0; + } else { + /* Absolute path */ + return plat_file_check(fn); + } +} + uint8_t rom_read(uint32_t addr, void *priv) { diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index d8c2abdbc..3e23d8682 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: German \n" +"Language: de-DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: de_DE\n" "X-Source-Language: en_US\n" @@ -448,7 +454,7 @@ msgid "MIDI In Device:" msgstr "MIDI Eingabegerät:" msgid "MIDI Out:" -msgstr "" +msgstr "MIDI Ausgang:" msgid "Standalone MPU-401" msgstr "Eigenständiges-MPU-401-Gerät" @@ -490,7 +496,7 @@ msgid "LPT4 Device:" msgstr "LPT4-Gerät:" msgid "Internal LPT ECP DMA:" -msgstr "" +msgstr "DMA des ECP des internen Parallelports:" msgid "Serial port 1" msgstr "Serielle Schnittstelle 1" @@ -610,7 +616,7 @@ msgid "MO drives:" msgstr "MO-Laufwerke:" msgid "MO:" -msgstr "" +msgstr "MO:" msgid "Removable disks:" msgstr "Wechseldatenträger:" @@ -754,7 +760,7 @@ msgid "Hard disks" msgstr "Festplatten" msgid "Disks:" -msgstr "" +msgstr "Festplatten:" msgid "Floppy:" msgstr "Diskette:" @@ -1147,7 +1153,7 @@ msgid "%1 total" msgstr "%1 insgesamt" msgid "VMs: %1" -msgstr "" +msgstr "VMs: %1" msgid "System Directory:" msgstr "Systemverzeichnis:" @@ -1318,10 +1324,10 @@ msgid "Some files in the machine's directory were unable to be deleted. Please d msgstr "Eine Dateien im Verzeichnis der Maschine konnten nicht gelöscht werden, bitte lösche diese manuell." msgid "Build" -msgstr "" +msgstr "Build" msgid "Version" -msgstr "" +msgstr "Version" msgid "An update to 86Box is available: %1 %2" msgstr "Eine Aktualisierung für 86Box is verfügbar: %1 %2" @@ -1363,22 +1369,22 @@ msgid "Found %1" msgstr "Gefunden %1" msgid "System" -msgstr "" +msgstr "System" msgid "Storage" msgstr "Speicherplatz" msgid "Disk %1:" -msgstr "" +msgstr "Festplatte %1:" msgid "No disks" msgstr "Keine Disks" msgid "Audio" -msgstr "" +msgstr "Klang" msgid "Audio:" -msgstr "" +msgstr "Klang:" msgid "ACPI shutdown" msgstr "Über ACPI herunterfahren" @@ -1819,7 +1825,7 @@ msgid "VDE Socket:" msgstr "VDE Anschluss:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "TAP-Brückengerät:" msgid "86Box Unit Tester" msgstr "86Box-Gerätetester" @@ -2212,16 +2218,16 @@ msgid "WSS DMA" msgstr "WSS-DMA" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ der RTC" msgid "RTC Port Address" -msgstr "" +msgstr "Portadresse der RTC" msgid "Onboard RTC" -msgstr "" +msgstr "Integrierte RTC" msgid "Not installed" -msgstr "" +msgstr "Nicht installiert" msgid "Enable OPL" msgstr "OPL einschalten" @@ -2845,7 +2851,7 @@ msgid "Toggle fullscreen" msgstr "Vollbild umschalten" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "UI im Vollbildmodus umschalten" msgid "Screenshot" msgstr "Bildschirmaufnahme" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index e1163d9d7..a365d62aa 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Spanish \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: es_ES\n" "X-Source-Language: en_US\n" @@ -1819,7 +1825,7 @@ msgid "VDE Socket:" msgstr "Toma VDE:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Dispositivo puente TAP:" msgid "86Box Unit Tester" msgstr "Comprobador de unidad 86Box" @@ -2212,16 +2218,16 @@ msgid "WSS DMA" msgstr "DMA de WSS" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ RTC" msgid "RTC Port Address" -msgstr "" +msgstr "Dirección puerta RTC" msgid "Onboard RTC" -msgstr "" +msgstr "RTC integrado" msgid "Not installed" -msgstr "" +msgstr "No instalado" msgid "Enable OPL" msgstr "Habilitar OPL" @@ -2845,7 +2851,7 @@ msgid "Toggle fullscreen" msgstr "Alternar pantalla completa" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Alternar interfaz de usuario en modo de pantalla completa" msgid "Screenshot" msgstr "Captura de pantalla" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index ec7734bb0..d51553ba6 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: French \n" +"Language: fr-FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: fr_FR\n" "X-Source-Language: en_US\n" @@ -1819,7 +1825,7 @@ msgid "VDE Socket:" msgstr "Prise VDE :" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Dispositif de pont TAP :" msgid "86Box Unit Tester" msgstr "Testeur d'unité de 86Box" @@ -2212,16 +2218,16 @@ msgid "WSS DMA" msgstr "DMA WSS" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ du horloge en temps réel" msgid "RTC Port Address" -msgstr "" +msgstr "Addresse du port du horloge en temps réel" msgid "Onboard RTC" -msgstr "" +msgstr "Horloge en temps réel integré" msgid "Not installed" -msgstr "" +msgstr "Non installé" msgid "Enable OPL" msgstr "Activer OPL" @@ -2845,7 +2851,7 @@ msgid "Toggle fullscreen" msgstr "Activer/désactiver le mode plein écran" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Basculer l'interface utilisateur en mode plein écran" msgid "Screenshot" msgstr "Capture d'écran" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index ea41d19c3..ee6c238b9 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1,8 +1,16 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Croatian " +"\n" +"Language: hr-HR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: hr_HR\n" "X-Source-Language: en_US\n" @@ -1819,7 +1827,7 @@ msgid "VDE Socket:" msgstr "VDE utičnica:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Mostovni uređaj TAP:" msgid "86Box Unit Tester" msgstr "Jedinični ispitivač 86Box-a" @@ -2212,16 +2220,16 @@ msgid "WSS DMA" msgstr "DMA WSS-a" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ sata u stvarnom vremenu" msgid "RTC Port Address" -msgstr "" +msgstr "Adresa sata u stvarnom vremenu" msgid "Onboard RTC" -msgstr "" +msgstr "Integrirani sat u stvarnom vremenu" msgid "Not installed" -msgstr "" +msgstr "Nije instaliran" msgid "Enable OPL" msgstr "Omogući OPL" @@ -2845,7 +2853,7 @@ msgid "Toggle fullscreen" msgstr "Uključi/isključi cijelozaslonski način" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Prebaci korisničko sučelje u načinu cijelog zaslona" msgid "Screenshot" msgstr "Snimka zaslona" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index d739672e0..533377b46 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Italian \n" +"Language: it-IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: it_IT\n" "X-Source-Language: en_US\n" @@ -1819,7 +1825,7 @@ msgid "VDE Socket:" msgstr "Presa VDE:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Dispositivo ponte TAP:" msgid "86Box Unit Tester" msgstr "Tester di unità 86Box" @@ -2212,16 +2218,16 @@ msgid "WSS DMA" msgstr "DMA WSS" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ dell'ora in tempo reale" msgid "RTC Port Address" -msgstr "" +msgstr "Indirizzo porta dell'ora in tempo reale" msgid "Onboard RTC" -msgstr "" +msgstr "Ora in tempo reale integrata" msgid "Not installed" -msgstr "" +msgstr "Non installato" msgid "Enable OPL" msgstr "Abilita OPL" @@ -2845,7 +2851,7 @@ msgid "Toggle fullscreen" msgstr "Attiva/disattiva schermo intero" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Attivare/disattivare interfaccia utente in modalità a schermo intero" msgid "Screenshot" msgstr "Istantanea dello schermo" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 3b515edbc..8d117f349 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1,8 +1,15 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Japanese " +"\n" +"Language: ja-JP\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: ja_JP\n" "X-Source-Language: en_US\n" @@ -1819,7 +1826,7 @@ msgid "VDE Socket:" msgstr "VDEソケット:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "TAP ブリッジデバイス:" msgid "86Box Unit Tester" msgstr "86Boxユニットテスター" @@ -2212,16 +2219,16 @@ msgid "WSS DMA" msgstr "WSS DMA" msgid "RTC IRQ" -msgstr "" +msgstr "RTCのIRQ" msgid "RTC Port Address" -msgstr "" +msgstr "RTCのポートアドレス" msgid "Onboard RTC" -msgstr "" +msgstr "オンボード RTC" msgid "Not installed" -msgstr "" +msgstr "インストールされていません" msgid "Enable OPL" msgstr "OPLを有効にする" @@ -2845,7 +2852,7 @@ msgid "Toggle fullscreen" msgstr "フルスクリーン表示を切り替える" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "全画面表示時にUIを切り替える" msgid "Screenshot" msgstr "スクリーンショット" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 3316cdf29..177ef25f6 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1,8 +1,15 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Portuguese (Portugal) \n" +"Language: pt-PT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: pt_PT\n" "X-Source-Language: en_US\n" @@ -178,7 +185,7 @@ msgid "BT&709 (HDTV)" msgstr "BT&709 (HDTV)" msgid "&Average" -msgstr "&Media" +msgstr "&Média" msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgstr "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA" @@ -334,7 +341,7 @@ msgid "Configure" msgstr "Configurar" msgid "CPU:" -msgstr "" +msgstr "Processador:" msgid "CPU type:" msgstr "Tipo do CPU:" @@ -685,7 +692,7 @@ msgid "86Box could not find any usable ROM images.\n\nPlease descarregue um pacote ROM e instale-o na pasta \"roms\"." msgid "(empty)" -msgstr "(empty)" +msgstr "(vazio)" msgid "All files" msgstr "Todos os ficheiros" @@ -868,7 +875,7 @@ msgid "6-button gamepad" msgstr "Manípulo(s) de jogos de 6 botões" msgid "Gravis PC GamePad" -msgstr "Gravis PC GamePad" +msgstr "GamePad Gravis PC" msgid "2-button flight yoke" msgstr "Manípulo de voo de 2 botões" @@ -910,37 +917,37 @@ msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + Pedais CH" msgid "CH Flightstick Pro + CH Pedals Pro" -msgstr "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + Pedais CH Pro" msgid "CH Virtual Pilot" msgstr "CH Virtual Pilot" msgid "CH Virtual Pilot + CH Pedals" -msgstr "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + Pedais CH" msgid "CH Virtual Pilot + CH Pedals Pro" -msgstr "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + Pedais CH Pro" msgid "CH Virtual Pilot Pro" msgstr "CH Virtual Pilot Pro" msgid "CH Virtual Pilot Pro + CH Pedals" -msgstr "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + Pedais CH" msgid "CH Virtual Pilot Pro + CH Pedals Pro" -msgstr "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + Pedais CH Pro" msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgstr "Sistema de controlo de voo Thrustmaster" msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgstr "SCV Thrustmaster + Sistema de controlo do leme" msgid "Thrustmaster Formula T1/T2 with adapter" msgstr "Thrustmaster Formula T1/T2 com adaptador" @@ -1693,7 +1700,7 @@ msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Apl&icar o modo de estiramento na tela cheia quando maximizado" msgid "&Cursor/Puck" -msgstr "&Cursor/Puck" +msgstr "&Cursor/Disco" msgid "&Pen" msgstr "C&aneta" @@ -1738,7 +1745,7 @@ msgid " fps" msgstr " fps" msgid "VSync" -msgstr "VSync" +msgstr "Sincronização vertical" msgid "Synchronize with video" msgstr "Sincronizar com vídeo" @@ -1819,7 +1826,7 @@ msgid "VDE Socket:" msgstr "Tomada VDE:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Dispositivo Ponte TAP:" msgid "86Box Unit Tester" msgstr "Testador de unidades 86Box" @@ -2212,16 +2219,16 @@ msgid "WSS DMA" msgstr "WSS DMA" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ RTC" msgid "RTC Port Address" -msgstr "" +msgstr "Endereço Porta RTC" msgid "Onboard RTC" -msgstr "" +msgstr "RTC Integrado" msgid "Not installed" -msgstr "" +msgstr "Não instalado" msgid "Enable OPL" msgstr "Ativar OPL" @@ -2311,7 +2318,7 @@ msgid "Video chroma-keying" msgstr "Utilizar a chave chroma do vídeo" msgid "Dithering" -msgstr "Dithering" +msgstr "Pontilhamento" msgid "Enable NMI for CGA emulation" msgstr "Ativar NMI para emulação CGA" @@ -2845,7 +2852,7 @@ msgid "Toggle fullscreen" msgstr "Alternar o modo em ecrã cheio" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Alternar interface do utilizador em ecrã inteiro" msgid "Screenshot" msgstr "Captura de ecrã" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 5ec7d4b59..5f84e59fe 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Slovak \n" +"Language: sk-SK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: sk_SK\n" "X-Source-Language: en_US\n" @@ -1819,7 +1825,7 @@ msgid "VDE Socket:" msgstr "Zásuvka VDE:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Mostové zariadenie TAP:" msgid "86Box Unit Tester" msgstr "86Box Unit Tester" @@ -2212,16 +2218,16 @@ msgid "WSS DMA" msgstr "WSS DMA" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ hodin reálneho času" msgid "RTC Port Address" -msgstr "" +msgstr "Adresa hodin reálneho času" msgid "Onboard RTC" -msgstr "" +msgstr "Integrované hodiny reálneho času" msgid "Not installed" -msgstr "" +msgstr "Nie je nainštalované" msgid "Enable OPL" msgstr "Povolenie OPL" @@ -2845,7 +2851,7 @@ msgid "Toggle fullscreen" msgstr "Prepnúť režim celej obrazovky" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Prepnúť používateľské rozhranie v režime celej obrazovky" msgid "Screenshot" msgstr "Zhotoviť snímku obrazovky" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 5b35eb615..b654c9889 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1,8 +1,16 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Slovenian " +"\n" +"Language: sl-SI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " +"n%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: sl_SI\n" "X-Source-Language: en_US\n" @@ -1819,7 +1827,7 @@ msgid "VDE Socket:" msgstr "Vtičnica VDE:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Mostovna naprava TAP:" msgid "86Box Unit Tester" msgstr "Tester enote 86Box" @@ -2212,16 +2220,16 @@ msgid "WSS DMA" msgstr "DMA WSS" msgid "RTC IRQ" -msgstr "" +msgstr "IRQ ure v realnem času" msgid "RTC Port Address" -msgstr "" +msgstr "Naslov ure v realnem času" msgid "Onboard RTC" -msgstr "" +msgstr "Integrirana ura v realnem času" msgid "Not installed" -msgstr "" +msgstr "Ni nameščen" msgid "Enable OPL" msgstr "Omogoči OPL" @@ -2845,7 +2853,7 @@ msgid "Toggle fullscreen" msgstr "Preklopi celozaslonski način" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Preklopi uporabniški vmesnik v načinu polnega zaslona" msgid "Screenshot" msgstr "Zajem zaslona" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index c67d9c66b..e98da1f0c 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1,8 +1,16 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Ukrainian " +"\n" +"Language: uk-UA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: uk_UA\n" "X-Source-Language: en_US\n" @@ -1819,7 +1827,7 @@ msgid "VDE Socket:" msgstr "VDE сокет:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "Пристрій моста TAP:" msgid "86Box Unit Tester" msgstr "Тестер блоків 86Box" @@ -2215,13 +2223,13 @@ msgid "RTC IRQ" msgstr "IRQ RTC" msgid "RTC Port Address" -msgstr "" +msgstr "Адреса порту RTC" msgid "Onboard RTC" -msgstr "" +msgstr "Вбудований RTC" msgid "Not installed" -msgstr "" +msgstr "Не встановлен" msgid "Enable OPL" msgstr "Ввімкнути OPL" @@ -2845,7 +2853,7 @@ msgid "Toggle fullscreen" msgstr "Переключити повноекранний режим" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "Переключити UI в повноекранному режимі" msgid "Screenshot" msgstr "Скріншот" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 06f375609..96951cdd7 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -109,10 +109,10 @@ msgid "Fi<er method" msgstr "过滤方式(&L)" msgid "&Nearest" -msgstr "邻近(&N)" +msgstr "近邻取样(&N)" msgid "&Linear" -msgstr "线性(&L)" +msgstr "线性过滤(&L)" msgid "Hi&DPI scaling" msgstr "HiDPI 缩放(&D)" @@ -364,7 +364,7 @@ msgid "Disabled" msgstr "禁用" msgid "Enabled (local time)" -msgstr "启用 (本地时间)" +msgstr "启用 (本地时区)" msgid "Enabled (UTC)" msgstr "启用 (UTC)" @@ -454,10 +454,10 @@ msgid "Standalone MPU-401" msgstr "独立 MPU-401" msgid "Use FLOAT32 sound" -msgstr "使用单精度浮点 (FLOAT32) 音频" +msgstr "使用单精度浮点(FLOAT32)音频" msgid "FM synth driver" -msgstr "FM synth driver" +msgstr "FM合成器驱动" msgid "Nuked (more accurate)" msgstr "Nuked (更准确)" @@ -1171,7 +1171,7 @@ msgid "Use regular expressions in search box" msgstr "在搜索框中使用正则表达式" msgid "%1 machine(s) are currently active. Are you sure you want to exit the VM manager anyway?" -msgstr "%1 计算机当前处于活动状态。您确定要退出虚拟机管理器吗?" +msgstr "%1 个计算机当前处于活动状态。您确定要退出虚拟机管理器吗?" msgid "Add new system wizard" msgstr "添加新系统向导" @@ -1819,10 +1819,10 @@ msgid "VDE Socket:" msgstr "VDE 套接字:" msgid "TAP Bridge Device:" -msgstr "" +msgstr "TAP 桥接设备:" msgid "86Box Unit Tester" -msgstr "86Box 装置测试仪" +msgstr "86Box 单元测试工具" msgid "Novell NetWare 2.x Key Card" msgstr "Novell NetWare 2.x 密钥卡" @@ -2134,7 +2134,7 @@ msgid "MAC Address" msgstr "MAC 地址" msgid "MAC Address OUI" -msgstr "MAC 地址的 OUI" +msgstr "MAC 地址组织唯一标识符" msgid "Enable BIOS" msgstr "启用 BIOS" @@ -2212,16 +2212,16 @@ msgid "WSS DMA" msgstr "WSS DMA" msgid "RTC IRQ" -msgstr "" +msgstr "实时时钟的IRQ" msgid "RTC Port Address" -msgstr "" +msgstr "实时时钟的端口地址" msgid "Onboard RTC" -msgstr "" +msgstr "板载实时时钟" msgid "Not installed" -msgstr "" +msgstr "未安装" msgid "Enable OPL" msgstr "启用 OPL" @@ -2350,7 +2350,7 @@ msgid "Transfer Speed" msgstr "传输速度" msgid "EMS mode" -msgstr "EMS (扩展内存)模式" +msgstr "EMS(扩展内存)模式" msgid "EMS Address" msgstr "EMS 地址" @@ -2491,7 +2491,7 @@ msgid "24 MB" msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" -msgstr "SigmaTel STAC9721T (立体声)" +msgstr "SigmaTel STAC9721T(立体声)" msgid "256 KB" msgstr "256 KB" @@ -2845,7 +2845,7 @@ msgid "Toggle fullscreen" msgstr "切换全屏" msgid "Toggle UI in fullscreen" -msgstr "" +msgstr "在全屏模式下激活菜单栏" msgid "Screenshot" msgstr "截图" @@ -2944,13 +2944,13 @@ msgid "build" msgstr "构建" msgid "You are currently running version %1." -msgstr "您当前正在运行版本 %1 。" +msgstr "您当前正在运行版本 %1。" msgid "Version %1 is now available." msgstr "版本 %1现已可用。" msgid "You are currently running build %1." -msgstr "您当前正在运行构建 %1 。" +msgstr "您当前正在运行构建 %1。" msgid "Build %1 is now available." msgstr "构建 %1现已可用。" diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 31eb09e56..a042d8b7d 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -836,6 +836,30 @@ plat_init_rom_paths(void) } } +void +plat_init_asset_paths(void) +{ + auto paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + +#ifdef _WIN32 + // HACK: The standard locations returned for GenericDataLocation include + // the EXE path and a `data` directory within it as the last two entries. + + // Remove the entries as we don't need them. + paths.removeLast(); + paths.removeLast(); +#endif + + for (auto &path : paths) { +#ifdef __APPLE__ + asset_add_path(QDir(path).filePath("net.86Box.86Box/assets").toUtf8().constData()); + asset_add_path(QDir(path).filePath("86Box/assets").toUtf8().constData()); +#else + asset_add_path(QDir(path).filePath("86Box/assets").toUtf8().constData()); +#endif + } +} + void plat_get_cpu_string(char *outbuf, uint8_t len) { diff --git a/src/unix/unix.c b/src/unix/unix.c index 716fec109..ce644cac6 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -896,6 +896,82 @@ plat_init_rom_paths(void) rom_add_path(default_rom_path); #endif } + +void +plat_init_asset_paths(void) +{ +#ifndef __APPLE__ + const char *xdg_data_home = getenv("XDG_DATA_HOME"); + if (xdg_data_home) { + char xdg_asset_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(xdg_asset_path, sizeof(xdg_asset_path), "%s/", xdg_data_home); + if (used < sizeof(xdg_asset_path)) + used += snprintf(xdg_asset_path + used, sizeof(xdg_asset_path) - used, "86Box/"); + if (used < sizeof(xdg_asset_path) && !plat_dir_check(xdg_asset_path)) + plat_dir_create(xdg_asset_path); + if (used < sizeof(xdg_asset_path)) + used += snprintf(xdg_asset_path + used, sizeof(xdg_asset_path) - used, "assets/"); + if (used < sizeof(xdg_asset_path) && !plat_dir_check(xdg_asset_path)) + plat_dir_create(xdg_asset_path); + if (used < sizeof(xdg_asset_path)) + asset_add_path(xdg_asset_path); + } else { + const char *home = getenv("HOME"); + if (!home) { + struct passwd *pw = getpwuid(getuid()); + if (pw) + home = pw->pw_dir; + } + + if (home) { + char home_asset_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(home_asset_path, sizeof(home_asset_path), + "%s/.local/share/86Box/", home); + if (used < sizeof(home_asset_path) && !plat_dir_check(home_asset_path)) + plat_dir_create(home_asset_path); + if (used < sizeof(home_asset_path)) + used += snprintf(home_asset_path + used, + sizeof(home_asset_path) - used, "assets/"); + if (used < sizeof(home_asset_path) && !plat_dir_check(home_asset_path)) + plat_dir_create(home_asset_path); + if (used < sizeof(home_asset_path)) + asset_add_path(home_asset_path); + } + } + + const char *xdg_data_dirs = getenv("XDG_DATA_DIRS"); + if (xdg_data_dirs) { + char *xdg_asset_paths = strdup(xdg_data_dirs); + if (xdg_asset_paths) { + // Trim trailing colons + size_t len = strlen(xdg_asset_paths); + while (len > 0 && xdg_asset_paths[len - 1] == ':') + xdg_asset_paths[--len] = '\0'; + + char *saveptr = NULL; + char *cur_xdg = strtok_r(xdg_asset_paths, ":", &saveptr); + while (cur_xdg) { + char real_xdg_asset_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(real_xdg_asset_path, + sizeof(real_xdg_asset_path), + "%s/86Box/assets/", cur_xdg); + if (used < sizeof(real_xdg_asset_path)) + asset_add_path(real_xdg_asset_path); + cur_xdg = strtok_r(NULL, ":", &saveptr); + } + + free(xdg_asset_paths); + } + } else { + asset_add_path("/usr/local/share/86Box/assets/"); + asset_add_path("/usr/share/86Box/assets/"); + } +#else + char default_asset_path[TMP_PATH_BUFSIZE] = {0}; + getDefaultROMPath(default_asset_path); + asset_add_path(default_asset_path); +#endif +} #undef TMP_PATH_BUFSIZE void