From 9063bbe68bc910f269cd2cfd799496d8a40893c1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 23 Jul 2025 15:53:34 +0200 Subject: [PATCH] Second and last part of the icon indicator work. --- src/config.c | 251 +++++++++++----------------- src/device/cassette.c | 16 +- src/disk/mo.c | 13 +- src/disk/zip.c | 13 +- src/floppy/fdd.c | 12 +- src/include/86box/cassette.h | 2 +- src/qt/icons/browse.ico | Bin 0 -> 9622 bytes src/qt/icons/cartridge_image.ico | Bin 0 -> 9622 bytes src/qt/icons/cassette_image.ico | Bin 0 -> 9622 bytes src/qt/icons/cdrom_nomedia.ico | Bin 0 -> 9622 bytes src/qt/icons/eject.ico | Bin 0 -> 9622 bytes src/qt/icons/export.ico | Bin 0 -> 9622 bytes src/qt/icons/fast_forward.ico | Bin 0 -> 9622 bytes src/qt/icons/floppy_35_image.ico | Bin 0 -> 9622 bytes src/qt/icons/floppy_525_image.ico | Bin 0 -> 9622 bytes src/qt/icons/mo_image.ico | Bin 0 -> 9622 bytes src/qt/icons/new.ico | Bin 0 -> 9622 bytes src/qt/icons/record.ico | Bin 0 -> 9622 bytes src/qt/icons/rewind.ico | Bin 0 -> 9622 bytes src/qt/icons/superdisk.ico | Bin 0 -> 9622 bytes src/qt/icons/superdisk_disabled.ico | Bin 0 -> 9622 bytes src/qt/icons/superdisk_image.ico | Bin 0 -> 9622 bytes src/qt/icons/write_active.ico | Bin 9622 -> 6950 bytes src/qt/icons/write_protected.ico | Bin 9622 -> 9622 bytes src/qt/icons/zip_image.ico | Bin 0 -> 9622 bytes src/qt/qt_iconindicators.cpp | 18 +- src/qt/qt_iconindicators.hpp | 5 + src/qt/qt_machinestatus.cpp | 28 +++- src/qt/qt_mediahistorymanager.cpp | 46 +++-- src/qt/qt_mediamenu.cpp | 164 +++++++++++++----- src/qt_resources.qrc | 16 ++ 31 files changed, 362 insertions(+), 222 deletions(-) create mode 100644 src/qt/icons/browse.ico create mode 100644 src/qt/icons/cartridge_image.ico create mode 100644 src/qt/icons/cassette_image.ico create mode 100644 src/qt/icons/cdrom_nomedia.ico create mode 100644 src/qt/icons/eject.ico create mode 100644 src/qt/icons/export.ico create mode 100644 src/qt/icons/fast_forward.ico create mode 100644 src/qt/icons/floppy_35_image.ico create mode 100644 src/qt/icons/floppy_525_image.ico create mode 100644 src/qt/icons/mo_image.ico create mode 100644 src/qt/icons/new.ico create mode 100644 src/qt/icons/record.ico create mode 100644 src/qt/icons/rewind.ico create mode 100644 src/qt/icons/superdisk.ico create mode 100644 src/qt/icons/superdisk_disabled.ico create mode 100644 src/qt/icons/superdisk_image.ico create mode 100644 src/qt/icons/zip_image.ico diff --git a/src/config.c b/src/config.c index 95362bc06..9aa4a15e5 100644 --- a/src/config.c +++ b/src/config.c @@ -795,6 +795,33 @@ load_ports(void) #endif } +static int +load_image_file(char *dest, char *p, uint8_t *ui_wp) +{ + char *prefix = ""; + int ret = 0; + + if (strstr(p, "wp://") == p) { + p += 5; + prefix = "wp://"; + if (ui_wp != NULL) + *ui_wp = 1; + } else if ((ui_wp != NULL) && *ui_wp) + prefix = "wp://"; + + if (path_abs(p)) { + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s", prefix, p); + } else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, usr_path, path_get_slash(usr_path), p); + + path_normalize(dest); + + return ret; +} + /* Load "Storage Controllers" section. */ static void load_storage_controllers(void) @@ -888,20 +915,17 @@ load_storage_controllers(void) else cassette_enable = 0; + cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0); + ini_section_delete_var(cat, "cassette_writeprot"); + p = ini_section_get_string(cat, "cassette_file", ""); if (!strcmp(p, usr_path)) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of cassette_file is more than 511\n"); - else - strncpy(cassette_fname, p, 511); - } else - path_append_filename(cassette_fname, usr_path, p); - path_normalize(cassette_fname); + if (load_image_file(cassette_fname, p, (uint8_t *) &cassette_ui_writeprot)) + fatal("Configuration: Length of cassette_file is more than 511\n"); } p = ini_section_get_string(cat, "cassette_mode", "load"); @@ -915,16 +939,9 @@ load_storage_controllers(void) sprintf(temp, "cassette_image_history_%02i", i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("Configuration: Length of cassette_image_history_%02i is more " - "than %i\n", i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(cassette_image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(cassette_image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(cassette_image_history[i]); + if (load_image_file(cassette_image_history[i], p, NULL)) + fatal("Configuration: Length of cassette_image_history_%02i is more " + "than %i\n", i + 1, MAX_IMAGE_PATH_LEN - 1); } } cassette_pos = ini_section_get_int(cat, "cassette_position", 0); @@ -939,9 +956,6 @@ load_storage_controllers(void) cassette_pcm = ini_section_get_int(cat, "cassette_pcm", 0); if (!cassette_pcm) ini_section_delete_var(cat, "cassette_pcm"); - cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0); - if (!cassette_ui_writeprot) - ini_section_delete_var(cat, "cassette_writeprot"); if (!cassette_enable) { ini_section_delete_var(cat, "cassette_file"); @@ -1227,6 +1241,11 @@ load_floppy_and_cdrom_drives(void) if (fdd_get_type(c) > 13) fdd_set_type(c, 13); + sprintf(temp, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0); + if (ui_writeprot[c] == 0) + ini_section_delete_var(cat, temp); + sprintf(temp, "fdd_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); @@ -1234,22 +1253,14 @@ load_floppy_and_cdrom_drives(void) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1); - else - strncpy(floppyfns[c], p, 511); - } else - path_append_filename(floppyfns[c], usr_path, p); - path_normalize(floppyfns[c]); + if (load_image_file(floppyfns[c], p, (uint8_t *) &(ui_writeprot[c]))) + fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1); } #if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif - sprintf(temp, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0); sprintf(temp, "fdd_%02i_turbo", c + 1); fdd_set_turbo(c, !!ini_section_get_int(cat, temp, 0)); sprintf(temp, "fdd_%02i_check_bpb", c + 1); @@ -1265,10 +1276,6 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_fn", c + 1); ini_section_delete_var(cat, temp); } - if (ui_writeprot[c] == 0) { - sprintf(temp, "fdd_%02i_writeprot", c + 1); - ini_section_delete_var(cat, temp); - } if (fdd_get_turbo(c) == 0) { sprintf(temp, "fdd_%02i_turbo", c + 1); ini_section_delete_var(cat, temp); @@ -1282,16 +1289,9 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("Configuration: Length of fdd_%02i_image_history_%02i is more " - "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(fdd_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(fdd_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(fdd_image_history[c][i]); + if (load_image_file(fdd_image_history[c][i], p, NULL)) + fatal("Configuration: Length of fdd_%02i_image_history_%02i is more " + "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } } @@ -1520,19 +1520,14 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_writeprot", c + 1); zip_drives[c].read_only = ini_section_get_int(cat, temp, 0); + ini_section_delete_var(cat, temp); if (!strcmp(p, usr_path)) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of zip_%02i_image_path is more than 511\n", c + 1); - else - strncpy(zip_drives[c].image_path, p, 511); - } else - path_append_filename(zip_drives[c].image_path, usr_path, p); - path_normalize(zip_drives[c].image_path); + if (load_image_file(zip_drives[c].image_path, p, &(zip_drives[c].read_only))) + fatal("Configuration: Length of zip_%02i_image_path is more than 511\n", c + 1); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { @@ -1540,16 +1535,9 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("Configuration: Length of zip_%02i_image_history_%02i is more than %i\n", - c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(zip_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(zip_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(zip_drives[c].image_history[i]); + if (load_image_file(zip_drives[c].image_history[i], p, NULL)) + fatal("Configuration: Length of zip_%02i_image_history_%02i is more than %i\n", + c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } @@ -1635,19 +1623,14 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_writeprot", c + 1); mo_drives[c].read_only = ini_section_get_int(cat, temp, 0); + ini_section_delete_var(cat, temp); if (!strcmp(p, usr_path)) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of mo_%02i_image_path is more than 511\n", c + 1); - else - strncpy(mo_drives[c].image_path, p, 511); - } else - path_append_filename(mo_drives[c].image_path, usr_path, p); - path_normalize(mo_drives[c].image_path); + if (load_image_file(mo_drives[c].image_path, p, &(mo_drives[c].read_only))) + fatal("Configuration: Length of mo_%02i_image_path is more than 511\n", c + 1); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { @@ -1655,16 +1638,9 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("Configuration: Length of mo_%02i_image_history_%02i is more than %i\n", - c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(mo_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(mo_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(mo_drives[c].image_history[i]); + if (load_image_file(mo_drives[c].image_history[i], p, NULL)) + fatal("Configuration: Length of mo_%02i_image_history_%02i is more than %i\n", + c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } @@ -2579,6 +2555,27 @@ save_keybinds(void) ini_delete_section_if_empty(config, cat); } +static void +save_image_file(char *cat, char *var, char *src) +{ + char temp[2048] = { 0 }; + char *prefix = ""; + + path_normalize(src); + + if (strstr(src, "wp://") == src) { + src += 5; + prefix = "wp://"; + } + + if (!strnicmp(src, usr_path, strlen(usr_path))) + sprintf(temp, "%s%s", prefix, &src[strlen(usr_path)]); + else + sprintf(temp, "%s%s", prefix, src); + + ini_section_set_string(cat, var, temp); +} + /* Save "Storage Controllers" section. */ static void save_storage_controllers(void) @@ -2640,13 +2637,8 @@ save_storage_controllers(void) if (strlen(cassette_fname) == 0) ini_section_delete_var(cat, "cassette_file"); - else { - path_normalize(cassette_fname); - if (!strnicmp(cassette_fname, usr_path, strlen(usr_path))) - ini_section_set_string(cat, "cassette_file", &cassette_fname[strlen(usr_path)]); - else - ini_section_set_string(cat, "cassette_file", cassette_fname); - } + else + save_image_file(cat, "cassette_file", cassette_fname); if (!strcmp(cassette_mode, "load")) ini_section_delete_var(cat, "cassette_mode"); @@ -2657,13 +2649,8 @@ save_storage_controllers(void) sprintf(temp, "cassette_image_history_%02i", i + 1); if ((cassette_image_history[i] == 0) || strlen(cassette_image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(cassette_image_history[i]); - if (!strnicmp(cassette_image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &cassette_image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, cassette_image_history[i]); - } + else + save_image_file(cat, temp, cassette_image_history[i]); } if (cassette_pos == 0) @@ -2686,10 +2673,7 @@ save_storage_controllers(void) else ini_section_set_int(cat, "cassette_pcm", cassette_pcm); - if (cassette_ui_writeprot == 0) - ini_section_delete_var(cat, "cassette_writeprot"); - else - ini_section_set_int(cat, "cassette_writeprot", cassette_ui_writeprot); + ini_section_delete_var(cat, "cassette_writeprot"); for (c = 0; c < 2; c++) { sprintf(temp, "cartridge_%02i_fn", c + 1); @@ -2944,19 +2928,11 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_writeprot", c + 1); ini_section_delete_var(cat, temp); - } else { - path_normalize(floppyfns[c]); - if (!strnicmp(floppyfns[c], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &floppyfns[c][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, floppyfns[c]); - } + } else + save_image_file(cat, temp, floppyfns[c]); sprintf(temp, "fdd_%02i_writeprot", c + 1); - if (ui_writeprot[c] == 0) - ini_section_delete_var(cat, temp); - else - ini_section_set_int(cat, temp, ui_writeprot[c]); + ini_section_delete_var(cat, temp); sprintf(temp, "fdd_%02i_turbo", c + 1); if (fdd_get_turbo(c) == 0) @@ -2974,13 +2950,8 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1); if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(fdd_image_history[c][i]); - if (!strnicmp(fdd_image_history[c][i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &fdd_image_history[c][i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, fdd_image_history[c][i]); - } + else + save_image_file(cat, temp, fdd_image_history[c][i]); } } @@ -3097,10 +3068,7 @@ save_other_removable_devices(void) ini_section_delete_var(cat, temp); sprintf(temp, "zip_%02i_writeprot", c + 1); - if (zip_drives[c].read_only) - ini_section_set_int(cat, temp, zip_drives[c].read_only); - else - ini_section_delete_var(cat, temp); + ini_section_delete_var(cat, temp); sprintf(temp, "zip_%02i_scsi_location", c + 1); if (zip_drives[c].bus_type != ZIP_BUS_SCSI) @@ -3114,25 +3082,15 @@ save_other_removable_devices(void) sprintf(temp, "zip_%02i_image_path", c + 1); if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - else { - path_normalize(zip_drives[c].image_path); - if (!strnicmp(zip_drives[c].image_path, usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &zip_drives[c].image_path[strlen(usr_path)]); - else - ini_section_set_string(cat, temp, zip_drives[c].image_path); - } + else + save_image_file(cat, temp, zip_drives[c].image_path); for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); if ((zip_drives[c].image_history[i] == 0) || strlen(zip_drives[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(zip_drives[c].image_history[i]); - if (!strnicmp(zip_drives[c].image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &zip_drives[c].image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, zip_drives[c].image_history[i]); - } + else + save_image_file(cat, temp, zip_drives[c].image_history[i]); } } @@ -3159,10 +3117,7 @@ save_other_removable_devices(void) ini_section_delete_var(cat, temp); sprintf(temp, "mo_%02i_writeprot", c + 1); - if (mo_drives[c].read_only) - ini_section_set_int(cat, temp, mo_drives[c].read_only); - else - ini_section_delete_var(cat, temp); + ini_section_delete_var(cat, temp); sprintf(temp, "mo_%02i_scsi_location", c + 1); if (mo_drives[c].bus_type != MO_BUS_SCSI) @@ -3176,25 +3131,15 @@ save_other_removable_devices(void) sprintf(temp, "mo_%02i_image_path", c + 1); if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - else { - path_normalize(mo_drives[c].image_path); - if (!strnicmp(mo_drives[c].image_path, usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &mo_drives[c].image_path[strlen(usr_path)]); - else - ini_section_set_string(cat, temp, mo_drives[c].image_path); - } + else + save_image_file(cat, temp, mo_drives[c].image_path); for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); if ((mo_drives[c].image_history[i] == 0) || strlen(mo_drives[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(mo_drives[c].image_history[i]); - if (!strnicmp(mo_drives[c].image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &mo_drives[c].image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, mo_drives[c].image_history[i]); - } + else + save_image_file(cat, temp, mo_drives[c].image_history[i]); } } diff --git a/src/device/cassette.c b/src/device/cassette.c index 5cde2fbd0..0577ae06f 100644 --- a/src/device/cassette.c +++ b/src/device/cassette.c @@ -152,10 +152,11 @@ pc_cas_del(pc_cassette_t *cas) } int -pc_cas_set_fname(pc_cassette_t *cas, const char *fname) +pc_cas_set_fname(pc_cassette_t *cas, char *fname) { unsigned n; const char *ext; + int offs = 0; if (cas->close) fclose(cas->fp); @@ -176,6 +177,13 @@ pc_cas_set_fname(pc_cassette_t *cas, const char *fname) return 0; } + if (strstr(fname, "wp://") == fname) { + offs = 5; + cassette_ui_writeprot = 1; + } + + fname += offs; + cas->fp = plat_fopen(fname, "r+b"); if (cas->fp == NULL) @@ -197,10 +205,10 @@ pc_cas_set_fname(pc_cassette_t *cas, const char *fname) n = strlen(fname); - cas->fname = malloc((n + 1) * sizeof(char)); + cas->fname = malloc((n + offs + 1) * sizeof(char)); if (cas->fname != NULL) - memcpy(cas->fname, fname, (n + 1) * sizeof(char)); + memcpy(cas->fname, fname - offs, (n + offs + 1) * sizeof(char)); if (n > 4) { ext = fname + (n - 4); @@ -216,6 +224,8 @@ pc_cas_set_fname(pc_cassette_t *cas, const char *fname) pc_cas_set_pcm(cas, 0); } + ui_sb_update_icon_wp(SB_CASSETTE, cassette_ui_writeprot); + return 0; } diff --git a/src/disk/mo.c b/src/disk/mo.c index 1a2db0443..c1f95c073 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -152,6 +152,14 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert) { const int was_empty = mo_is_empty(dev->id); int ret = 0; + int offs = 0; + + if (strstr(fn, "wp://") == fn) { + offs = 5; + dev->drv->read_only = 1; + } + + fn += offs; if (dev->drv == NULL) mo_eject(dev->id); @@ -202,7 +210,7 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert) log_fatal(dev->log, "mo_load(): Error seeking to the beginning of " "the file\n"); - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + strncpy(dev->drv->image_path, fn - offs, sizeof(dev->drv->image_path) - 1); ret = 1; } else @@ -218,6 +226,9 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert) if (was_empty) mo_insert((mo_t *) dev); } + + if (ret) + ui_sb_update_icon_wp(SB_MO | dev->id, dev->drv->read_only); } void diff --git a/src/disk/zip.c b/src/disk/zip.c index 55cf901a4..7602f8096 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -194,6 +194,14 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) { const int was_empty = zip_is_empty(dev->id); int ret = 0; + int offs = 0; + + if (strstr(fn, "wp://") == fn) { + offs = 5; + dev->drv->read_only = 1; + } + + fn += offs; if (dev->drv == NULL) zip_eject(dev->id); @@ -247,7 +255,7 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) log_fatal(dev->log, "zip_load(): Error seeking to the beginning of " "the file\n"); - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + strncpy(dev->drv->image_path, fn - offs, sizeof(dev->drv->image_path) - 1); /* After using strncpy, dev->drv->image_path needs to be explicitly null terminated to make gcc happy. @@ -270,6 +278,9 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) if (was_empty) zip_insert((zip_t *) dev); } + + if (ret) + ui_sb_update_icon_wp(SB_ZIP | dev->id, dev->drv->read_only); } void diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index b5eb8c8fc..dd87c19c0 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -459,11 +459,17 @@ fdd_load(int drive, char *fn) int size; const char *p; FILE *fp; + int offs = 0; fdd_log("FDD: loading drive %d with '%s'\n", drive, fn); if (!fn) return; + if (strstr(fn, "wp://") == fn) { + offs = 5; + ui_writeprot[drive] = 1; + } + fn += offs; p = path_get_extension(fn); if (!p) return; @@ -476,10 +482,10 @@ fdd_load(int drive, char *fn) while (loaders[c].ext) { if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { driveloaders[drive] = c; - if (floppyfns[drive] != fn) - strcpy(floppyfns[drive], fn); + if (floppyfns[drive] != (fn - offs)) + strcpy(floppyfns[drive], fn - offs); d86f_setup(drive); - loaders[c].load(drive, floppyfns[drive]); + loaders[c].load(drive, floppyfns[drive] + offs); drive_empty[drive] = 0; fdd_forced_seek(drive, 0); fdd_changed[drive] = 1; diff --git a/src/include/86box/cassette.h b/src/include/86box/cassette.h index 168d82099..dc85bfc26 100644 --- a/src/include/86box/cassette.h +++ b/src/include/86box/cassette.h @@ -75,7 +75,7 @@ void pc_cas_del(pc_cassette_t *cas); * @short Set the cassette file * @return True on error, false otherwise *****************************************************************************/ -int pc_cas_set_fname(pc_cassette_t *cas, const char *fname); +int pc_cas_set_fname(pc_cassette_t *cas, char *fname); /*!*************************************************************************** * @short Get the cassette mode diff --git a/src/qt/icons/browse.ico b/src/qt/icons/browse.ico new file mode 100644 index 0000000000000000000000000000000000000000..8a947ae9d375eb745363f03477518083ffe9a9a2 GIT binary patch literal 9622 zcmeHMy>1gh5MBfV0R<_7M3P^*ZtWEfEqPX*74|oo{Amc4z0#&RucW+|G`J+;`8fIrrE(x4WzN->y6N z70>S7)BE=~oqKlMx&3{;{{p>V7<(T&xCDYehj0&}*OyA?gxp7e3_TGrWK~t2Fk;=V z`l;^h;GnhbN#rx_P8)P5lNZDeJef@70OP6GMt3}Zq2m#w*(~@d#2Ak!(&Y0Pc9k?Y zj5BT1m+5Rqxsk@OLmduEr1{dIzi!{=Fr7{t?Gv2yw>ePKm01hlW5*bO&ZUoTjPt); z%TEOS9r%XG=^c@iJ&|f8QhJdcJiZU6d>5w-uj#wzdm?|8PA;&=!-=>BVv+q-zxs5x0QJ!ASX!Vu@^Z4AL9DE z$nV!Ut8i|WIJe3@kzMeuT7DRbya87p<7Az9ZlQ&C55RVAJw-2_nQXmeUo%B03*0+b zu$9A_%x1&K*qQNH{I0Qc`M(L<>)!31-c8uWQ0xMWlrazWU-M}(`M0qPJ=5X&g6C+x zZV+S{;5T5-)^oV#dEk9{w$A%t7eygt#<;2$wXE<=ZCPzEyr<1hR3Lxz`8;4!kv2>c z*L$_WIdlT92b_1|pS8OpiVZnY8|ue6MbVVczZYK*$$YfhVNSd6;k z|6TtXgH18AUJ}E?9^m+{bWx5C+x9?L+;}`~s2yg4wTy&1Q17pJ?2v1-!i%FJPMlAL{)My&=7MYS!xJie#Uwy@kFP6a#zr z)F|gbW>0q>+wa;}vQO|~e4pMvwY`k1lf|M6u{CM^6n(P3XUKcSy6xqAMo262$}!Au zD%r1F&)fICW8HqcUfX=hX`gWq>o`n&eZFQhm3`k^*5~duV_%5L`n>gdl}nxNv8cDf0ul$~yuTL4f=qjZ~&g%8 z_CHs$`k#I}X;AC`{kL;Ot-sg5mH+bRxKsK~%r*A3?b3{Wxm+gw88_u_J2p>^zqav> zgFp0VzmmSJ)c7xNeLJ>|k@b!I1st3QROj_#GU$6B?FVgz|Hog>5q>;{{`WCx_aW}- z{qxl|hLwdDFA)^lD1 zy+dx+#Pf?g9Pe=`8|d@_Av(#SM!HC zH1*r-9~r;KyvTOUu3O{sA7CdFyiZv$MY|br4J?3F5_}Jv12=%ahpqYHa+s3KO(pf! zJ>igYu{sAGJdmmLZ5fc6iW1iHE=lJaZNP-ly=v>Hx(yHaP8Sjfj-A&flat+Wz>)3 zqGzVh871S5J9pCe-~IG`!^aab>9ei&1I1rCOYD&IU!tpRpM!qiT$}zM@2iey_ZJ@> aI=C+q-kl?2PU8ML2ihj@;>~gWb33Z^REB(t#hB> zIk(w#{qOMmg=gQx2TdS!<1p?Dej}vCv%9ni*ECJL-ENEOu?PLzf)F?HS3g+tm!#+4 z;2kqM#-BWf**;>8^-p6R5faa*+IA71_2xXQRRBHC#SAL(YQ^?|*Nyk2ev|W;S<~EG=HRi8sJ4}pb_qPI zxyK~%-1saweHQK{c2bghu)ouB|V*B7O+MG5RcSXI#y=y4u3chQx@VkX0 zwEFnWp*CY!@yi){ru?WTS=%*&%#lQdGZw@V-ax0acti+w;qUuY=E-fwsYq|AIE|5c931$GCUW zQ=ZjQ;W=yry@Ki-*6#p-qT16mwoWZ@1Mq!_G|h19P3)pZvXT7B}XjcjK|a-!!IAz z&BxMl^D2H=&3E}Q1{=dWkdrDLJu_q#r+l7pr~KfdC?=~3JLn&OLuP2hkmt8ti*tw7d)3&$Q)+mA-0rP^ zWMOijSemyb+A!|I{c3&&f*AIq;U(9`nt_*@f%YDMXc(al{xE?z$>}l1PoNjj QOXxM!_G{XP{{WGZ{}B`&FaQ7m literal 0 HcmV?d00001 diff --git a/src/qt/icons/cdrom_nomedia.ico b/src/qt/icons/cdrom_nomedia.ico new file mode 100644 index 0000000000000000000000000000000000000000..ca3c58920b6ee508bf766e1c514d928a0d7c3a5e GIT binary patch literal 9622 zcmeHLJB}4G5cG-_2oXR)K(-qaasVVYLL7q#aSC{3gdBs2m~fA>CqNq#Acm@Tm#4?$ z@yzV5kU+1W{QT>#Dz`l!O-d)}G(CBeP@kvwrzyQoDLs9f``_=U^bKRrp5^}Mhbg^# zl+yWm?tewx5BNSu44Od5kYVKks@!$BO4u`0Pw1ladC z!f9)9?i|DaY>Ms12i??9vvsfyUW?@zOU}zw1LJ+(eA!q2!rWSX;c3MSXMw-OQVDZK ze-xUvRkz}~8pCI&xYaZ0iIR&@SHly1+uWl zVK{+w7WFkxU&b(&&n>({rxz%CZoS33^wIvQ4CqYP_3aj+Gdl2^&jpp4U1hgD|3DHh z>u7!z+qH*9XkF{;;q?lOxUrq*GP-fB+p1gsH^r~D+_nCIZ~5JVU$42fUikoDXQS-d$f3Qk+|#w}f#OGBY+GfRn_=UG z*pG3s5ZrCT(b6s&$1l2h`gDy73$^As#5S#P^zg|;jr8|l55Hg=17g;&3w}ngu}!CO zXWjKWHsOoIb7dT^ZwcRVsehmOeg=5Yo$Jr}*pFMQaGuHe;n+D=UX|Hn1doC`i{;!IsIJ?444NZQI?|A-~LIiP34SNHew zFKG~O#?u)a-<@k-^|$g1pK%QhHrB=({l!_=?YMB@(F~lH&)8?XkI~oAkIg#7S8G>3 z`WXK$Kd-UQ-fIuDk8)Vo{oF0)-?+6O%V)s2;bzu6M_c%*!gV+AE1VlO=scEnlbq+4 zCY<1}JoRhfH@Wqs(OyUkYw~$9ZvMfFhOKM&^-pq6oWO0`41MGjw`${-&zP_Ny5sC* zO=1VSp7Fv)EzY`@2EcNk_M2&Fa8rX@%{lAelv`?phI;K~eQ3;hId)s_prLSwwRidN ziaThqvy6O1o2)x?-rc&zUDw=`R;m4N(2r|twm%KSFMN;qiSH2C_~vkx9^l)=J$!pO YDJ8wcnf*`|j71;DFqRm^BIW?>Kkw2`!vFvP literal 0 HcmV?d00001 diff --git a/src/qt/icons/eject.ico b/src/qt/icons/eject.ico new file mode 100644 index 0000000000000000000000000000000000000000..1bfead4d6068671503da761fe5f717d590379a49 GIT binary patch literal 9622 zcmeHNy-ou$3^t+yAqE&2*yzZ}8?+P8!Gw5=p2Wh)V=yt(4JKX#iJhMbB#^@Qak3PJ zq`AwbP$XNj9Q%^b&ey9GDn!;~B)hu;JC?JN$gzm*?X~{RhR8Ky`}?hbu_bc4EixXr z{uS0eVeTQ;U7YHFmR6db`47FkMH3>LvzADgLd=XZ`iLWm*`Om(eFmg zCYB_^C@k7{v=^0pkBFJlL>ZZIY@Zs-EDavVdXyh4*{}8-<&2iG5-cs(#~g|kVh*WG zvDCJ;sb|(0Fa}nbfrfo~<{Yg*zJvb=eS`K9o?Ey=%Mn!1trOg(6QVtFkxeYkgxQDu z{+k*P>3z(R(@dFv{CE-X`mC(P954EODF1jlqn|VJhhXcji4*3ig&oUL8#~NVgA>IJ zZCiU7HQyL828;n?z+<49;M_XEoeP%Y`?oXa9uRwlen3lv_pmW^3e|g9!yhi=qGx3v z8%OFJ<(W~Uwazi-2EoxgMC#7io^#}CxM+UX&_`?SpF1eyfB4>42cge;P3^eQbyA%JYph};#BUNi&b=Hs_dap%bB0M3lIF^NiP0Z0lmSVLj{j4R&bfJ+l)t+uslChb^;v>>V70_4SU~*{<1e7}j_2 zd&9Gb@WCYz!aj_R;Fm!>0mE%<^lyq0eCYcKZHmF? zReuV#HZ51gh*j9KsT}l=`=D@R%lm;RK6AZm;j1skxV%omRs`gb5>FgCu*D%8pNH4E zMfh!CE7mr##Zhd@K*>PKz(2}>`!lAh8|W40tWEdN4X6dnHTS3YpJAH|=ddAk1l1fi z=8MbqOa8u8{|uTHx{6^o3s?*Nd3hcJKWC88XV;yF8GrjR@NDzSGi&~mZ6goFT%_Wx z+T1Y^FP=54e2dmO=TY&8C}!V_c)6F8Tfc!t`6o{`hBmkrL)9uTiea7Hj3wq@H+Rh6 z1$WHPJai>pa(8v+!do&>GEg#5GEg#5GVrf6fHw;l_><=tI)LKOpUJlS6J9`!@j?Q_ R%hYns{po!^hv(^+F5kkk$HV{t literal 0 HcmV?d00001 diff --git a/src/qt/icons/fast_forward.ico b/src/qt/icons/fast_forward.ico new file mode 100644 index 0000000000000000000000000000000000000000..6bc5eeaff16e0dca78ae41611c4f367135b3fcf0 GIT binary patch literal 9622 zcmb`LJ&qGW5QW?F3JVc#o1hJ+l0h#0a(1cV%c8z3VB!sb0j zrERsltE;+uS|i(2-}lNho}ZRO*o3QaeI4+63~#SOcojmpxmiDdeip(fY`eW(Kfiw- z!kZT%9FObgkMMqheF+C|k+5#ZOSp$uSYlyYx=F7;Jg{D8EOm`xtyPb)&d{~gzkDfY zh;ONvnAEq_b0+sK^^__3mbx6Xny=NR#&jC?;Ur+qJ}S+c+`Kk>}@foIQmJcGXBS@adpq(?lP9+wy%Pchsda2)pQ z%J>fV7 zS6&|Tr!A7-!&{s*zlU!*d43PCIi>s_zUI{Od-#&0<@fNp)5`DRQ^%6u!^<^g&G+!a z@+!0Bd-#;KZRLCT607BV_!?Ww_wX89%J=XsHqZC)7BOaHRGA#XP__Yjc z{~3NM!_$9;pJ#ac&+yZXp8hj@dFJ%?AMwTI^Qou*h@ZMW{YU)V_4Xg}ORlH?h+lK9 z{YQMwwe%nHTW+iWh;MPV{v*ECt@R)AJ#MN0i0^gt{v&>moAw{|c^~gtS@@pYSR+H04qaq0 Oib&V5LPA`G7Lphq)2C%l)Qmc@f=hPKQ90jzOySz9)pU3illK|01uJ}pr*)- z_&!;Cv(`x`oqdj(!8^0oolg6GtKF4!XJd}ci8((vXvgN&i80TOF&7uB`|C%>d_mvk zz zn?s1{W8TDw$s<4Q?T^=M!(;r68->qkOKI$Xz5xc5Ei`4XZCm#A!z;(d)RC$m;b#uf z-BO1Ke@JB}gFd_H&l_Saj9QP!SL(0A714EDsB z&E~ek{CUr3#PpY_lEk+oWD+?!C3(RT_xTi1GIE%zC0H*UY-ent6&J*tPaVh-C} zUlN`<@7j05XP&DQ&lPRKkKPwjfb_3aB6zL1Y>IdD0X5?_Tqm3OM=V$Cs9i1F_(weE zN9Sx?JgzM*L*V^){;3$2#LurWUAtzjUWn(l1ds8iaICDe7M?l>biQNP#M4;B)OhY1 z{&5~0SEAyVv@yIG4mp~21WwwqPjIB|!gCm~^>f+_9{r?`T4VENpB}?&nWJv+&B$u4 zac{CZ!I%n)b4w}DIG$U0g*MNia&EoAyYz+v{3cJO*Tqzfk=|o+*WQ<2__1{n>m&Cb z@P#wlGCrje`mbv*RiE49%X&`bZ3ukkBqc-ObAR5Y|KYi;=W_5L-!=bW{FxWO7sOh( z|8RY6TK_ultUbl&u=%6$Q#GV_#vyb=@Q z0Jsz1ae2S}SZCAaKgV&teeuP&Tr08M7GL}%p2S4zZV3M$0$*~{;Xj77g|Q1Y7k56_ zHf_{ZkFD|Xue3JDsF@Ny#kjK$9ogDU+^QljyXe5;1vt(;eh zCW-xnkl)?=`C~|I-9-D=&QRDB$J=+h(8XUeKgsVy@pDd6kK&)}W6o6F>}vi8{{6?F zIiMEgAH(v(T8XLPm$adMo^>_C{=uIP9a`g035+b!Q;a)`GI)!}j2*irU5b20r=ow68#^Waj82_9`XllkojU|j-@7}y zv`*4VcbC)!jsPKvA|H7qB{>mU$V$%71>;V>tVBMF$i+po{`p$u2V~oAv;O)<x8|MrRo|~iu08e0jGGvo6EkJ6HldNhTKQ4%SUfG9vn*IE zSM7YYbZ)fiXX$C0^h@Cu8wF-e=>f}32^{CIX*G_-uaySO=I;( zy$8p{Pg~-q;y6Wo#-zE`_*JHP(J>W2_d?7@^W`C#)#1J+SK*I;!y-%c*k7*9+{#7P z(Ay+=aki=df3SnY8?gQktN4%0X^7`xEDw%^HRbsq%5ChU{OA7e^7R<=?7w@TmK1~a zA4+rnJN>8qm_1IJe|tyf&ZqXDdf)V&u;c81+VjV{m(*a+|8)5;$-SP>f02Ls);A*8 zKlR$THZ<07Ip5!6sCy~#ukRG!9TU$1>m~fhd^3pW_Mh^d>z{WobO+Txlymx3%K3i1 z`(abZQBwcbM%{JB68{5Z*wo9KYU$%wLds%}w;7i%c PHEiy{dIyBZ590m+GThIg literal 0 HcmV?d00001 diff --git a/src/qt/icons/mo_image.ico b/src/qt/icons/mo_image.ico new file mode 100644 index 0000000000000000000000000000000000000000..c445ce385062a51c02c66aa3a9412d79645b6f8d GIT binary patch literal 9622 zcmeI2J(3hh5QU3?(1rqIF);9UO_{m@SUQI+g@8Nkv?&7!jv-5chq-rvbI6uKMC*N7 zl{MKt{X5+wIaEY${dDDfFSDxpXJS)&kRGKcPm=1}^!uZfen}}keVY59e@N*sjXiso z`+xkH(r=Gby1mW)Kjrtg=KdrfHHDDJRizj5TTxogowHH6rfJ&y`} zWA4Z5ypoKNYL(hZ?(*U1w`N!8I1@~OEk-vrUvaS@kSyzhXj6t-8vP2(v5vzm8TD*DF*)PnUGZPj5 zRDIx;wJ==8e0O)(9u5bq3B?L=lsq#QplZ`FneTI{wZ>qfkGg}GamKMA1`mA!a};l> zJ}`qF&=xFSqg?|Gjc@6ujn=52g7y3P+H=i00BL5=GqtICZs`>|{Ven6)~|Y(KC=kl zbg!uwQ?Zup(WO?jtisQmZvHPC{s(;L9IVOD($d#2z`Qxi`o+GtH{&C&oRxU4to`bh zoz+eHhwyoRU^>fN^s|X94{(qxzjsj=+k#)Q!2+LqExF=(z}SZmoAg(F&p-HJ2aa9z zJ3cje4;;JTgGqkMn)0}p_!xEvA8cY^U43t&Ut^9Fv1v2j!zNFiVp^FD{z#d^=b8X5 zX6g=j9>}Q7@fiFJC=RAf;d9;mGWImS-xC5p?>69%nPHc8%X0NM6cHZvgU?(H4jJzz zqwgni{)m34i~}CW4)r9y&zr+00`Q}r;yZ~S=g)C~KVS#t9wYzW9-7BkNPBIzjXwT^ zHR++|9j)I#Uc1t~>p{!!YS%3_?_syH7czejYxv=EpF&Jq?QA9Fob!LK744h&^WjBeR-TFV{=e-DXZRH*5BK*Ye@l(S~-Q(sRZBKsAyye{2fc*P=j&r*X;@7o3`71XZ z82s?SO|9=FGuoHrhmW}7C-+fy?h}6J zK*NNsiGPZ_!|(Y=gYS3W1H>Q3*6SdBseR5Y*PL`@m4tCnvfDZm%#DO5aowhdC`d)ec(?`Fze?-X` zLL^*&yZAW^Hpm<^X$WK>;NJCvcvD_RjC+i?Ak-NxH@@DWUV$F8MinB~nppNVz5RCh z4MB?MZZ@H}u1CHWp&pU@*i7sJ_EPrZ6ndNgY<-(JbMQmUMfTj*kKDH@$Mb`z$jy;QEPqQT!1{Lk#rgb1(XvOZ35BPl@qT1Y0SW zvTb$@0YktL_{Ru1cjDa7k#pZ8-DBzbTgn*6bIj{O*oRfh3uW%ZmN>W^j^ce8uZQp+ ze5Ji5^sarcW82f>eI2j4CMnoQi70G0?EU!aZ1xCP%N7f2=gUL-Z}5$HW7>(oGzO9X z*ymr@ek~<)VE$|G{-F8C*AwM{?^>LHjup>6zuZInk1PpmanM1JeNn;TpI@m}QX z2a(Oj)_-Z-Uv2wQWAsuH?0t1|r*WCZXuCG+3$J60`ZjyPY{7Bu@9&LiGlyB>co@b! zKDNiCaeRz1@nx~pWBURP=lGJbYvvErpe%4zKyV7q-@6aX9B<@36aYot8L0RgZ8Zv1N0W92PU4cf+vKm{a17!)j_g<1r^C z-p!k-^M`3Y4%2Dl5}6urxW=ZoP$TyC+;QN000|>X=)h_?2v=!oOt|L=W}?C z%zQsO4y(!b$H(F|pV!(MIKXqx#l9cPd^hGv&s#@5XC3sMwU?Eiy_S0JTD+K|u>XPg z+aLz9zyKC7fsJ$6M(s|G=ddllxEx;sEeaRc$1^k$JdQZmaXrw}L@K*e^EwXB(Ugzo z7Il}gR;}|n`?Zv>A*_`YZt4Acogo()W!OH{rzuavX}GDaTf=F&`!)Pe{&~35Ie5$b z^Y*Q@Lf=_zanzpLZ-iUmwyg9BXEpCXj| EAHYX{6aWAK literal 0 HcmV?d00001 diff --git a/src/qt/icons/rewind.ico b/src/qt/icons/rewind.ico new file mode 100644 index 0000000000000000000000000000000000000000..b18c1a66d39454710006ed5a4bc6aa6666085b29 GIT binary patch literal 9622 zcmb`LJ&x2s5JnpbArJ^}u)&5C5^hL<*o`;`5#ksQ$(Caf5wj7#!Ct{9U>!~{nxejG zwcNJ5tE;;0mNg#NdtZ4x9{-GUFWgIab>;Z=;J&|f?u&Eo`r5z$^UAs3yzb`4zyI;Z zxo>ZsI~@G`U+n#3_5(Y-$O(Quzqot$j1v`jsg7E0om}5bzEt)203^8TIEG@SnpN#BRh({P@_F(Bt@IL|D9@AD^{mo(hW$axxW$>j4i z+?Gk_X}C1A&C_ssW|^nsa6F{W!^n#Bv>d*BiH(mxEhlBhc@{3muJbHhicRHNxHX&0 zvv4shSvlXrr`deIh0n9;d=-iET>IOP?Jx!gX z@x7zroumG>3-=qBWvoLD3|KgDk#WgFCTHV5?7;Iq&*46-#~+vbPL}(uROc2y?3Yxo zW?hT#uQl4^cDpq#zISVmQ@)d?*7GLkC`?vTuciX?kx4X;!Z9c9en&%+&jOTFuY4vfn zsL2TZ_wZ{n;{JR1){J%kJ$y?>s{bCoHY3-64_}iZ_20uUWt95w;Y%5s{(Jbj3~m2C z{8Wae{~rE2!`gojKhCJ>zlR@Z)INV<+pYg2pl>|Ye*Tcr>LbTzghcx*`*h}U;&J3L y@fdjwJbE7d*Tb2|iN}%0#AD_vl#0dLYy}f?kuiw?QMQZ3-|Y7zqEl9vHN}4KRm>SG5Y?BbH{!fuNn~h z^z?MpBHpo9jc5K*k7wsN)d+qXPyMjOpayb#pH@6s=f+cm)Xd6ay)AuM=Q9`k#=d|461#?{SbQe7 zFwcdT)5hmKa#fvr4omtlpD^S5>p15jd*A2qFvt25BWIzJe$+VO*;0BhMP0|5a(I}7 zueK4$emsWT{Sa;}hqouT8^gIB-&^(x9o}2xd+VcpOINP3ezv}rJy2=BYxO6cC%@OY zzp&h6^q~_Ru$Wif8q?b+w&E!Ml+VaROe1by$v2)=#Zi3v!N!~-w13a&IFYCOfH=VD z!A}^q-aLGtLk*dAr*7Jsevhv;VLx#`*UtD-eN;oj$@TKsz4-LgGpBv($k|qXaxrt} z{uO+jzf!B!tEWEj(eDSGHyxMGK6qRB9-Hs8UXGW(QXWPJAQ}l4EW9(zrzOn;j($GeS%DEG_Re$)=7x(L&#@Lc=-T$SywdVixm*0Q68slE>ZMk?qH>dva)!#31ZrOC6 z{n~SfI(qp%xBt$E4)UsPY4{uXTe+harTkHgS`B*ge@Xrx?pFS_8np7qI$Jzf&wpR8 z@iVrx2Q_}I@jij|XI{s;|GX!Cd``n!{H#IL5o?6L>Yu~!wQH`uea{aqUc;2XxgP&N e2lLu`IlZ4^x(K}yEG#7XxQ zyuwh`wcmDk?Q~D?c|r0>i?^%XJ^J2!bP|Yn@tehhMzA(_&$X2@}=2-eHy|a zvi9ng*>67&;msEzY`12=m%M)@_G`(JOJT5efp8^xjbq;XTByGKj49(d#+((Dm^nL* zhn)NS`+{SZL&*)5-*SmFJ96w}LV%0h$H&LWA)c6T>+@`Jk$-<3+laBAqtqvkK1zLR zg9H7NgIujC9Q4Tr>7hi;u@eogh!}D~VnEixmOe2xgtMhz%VoW#Pfs8@U`rq0@4H>x zQ;=M6NuOMhT##J+dH<||%CCMoBC-yLuKP7?kX(>?Wd6YQsVJP`;d-8@ah`|EJ#O}> z>yxYx4ZNFYea^_^CO&WUd8NlYc}6vkVkQ#TveoC$1NDjh3J<@%9GCZoJzB=`z=hxT z1zzLydxh=MKcDbhf6AHe6Xr$l#PX~$q(1GqtjT6j)<+MX6YjFU5G;P4!Mr}WKsZXI zK3$Fdg~Vn3>L!;ybkq8B&-4qbR+=Amfwi7ZTXV~k_*Q+yctq13=w*_xr%lqn2d0+k5 zfq%#MmV82oZ{*~?^^<%{H;#DUi2o_5Ir&-0JasXJ*{XtG|uXJV%Z zezg*xX(YS;yMlWeef_0I&Y$$t`;k7Dx%2vMMrAy+xA`y&VnEi>sL#kWY|rV-xU~{J z;D8(S8pMIe_Yt+Hy@mr$kN9ht>Q+upxf%}|)%v~GskV*=ol|qy;^A%0e~n|!-%~$( zS;Lw}PyNL34%K?JUu-mM8m;<0H+HW^7GJ%8s1qay8+=OrEdHo|eB@$- ztb?_ESen1*zy_%wtZ8KNC)W=*2$!Fc`fEO7@z;HSu|vo?Zn1+UE3_34>>cYPu_2@WUVUHlH)iq4gse20zths*jAf5YNFCn{Hdsyh67 z9gj25cds`J`qOGbPsO?BKJYf{otSCz&diZ|(*3J7@H<5t?9>bvH!6+j+Zhe_4?dgA z(JXXsd#=+_IrVTF1z+;(9HPET9{RUFj`zg!Qk=I-?YxetQ}Fv5)@JRsmhGCR&ckY; zH?P0ce;FHs{|5B7?;pR@ihJSKs?Sm8vfQuVi(3E0r8#*0p8nTr@cl2xTMb^HKAAbl zI$X@OhW#}hW)XjHt^R!t)Uu5E9-yK3UViF2zM%Tm{bvr#TI{PwtHE;6N~r64XifBX zO8>Rlm+RKADV6^+3wk?$|7jj*m6)EZJ^fRs%`9>E+T_=;r+;#(w-?E)Av~@9ujQU= z{gnRCr3uf+)_?CkM;v|D@Ra_E<^LSIZ+hRz5s`JUw+79Jd#z5mi3gurLzXX3WPK*4 zXM?W=ZIE1$b&sCM+dchzPBg(<|Kxd1>@2_9KQVA&d&KW?ZLY2U(SQ@%<68f<8sL%q z|EzyBn7PMR|2`HjkG_9wpYLsWB>t#>eB@x)5Ka8pubT?FkIeD(=S{3`@=?X+^>sY<95%6;r2`UyTl}a Kml!?(@BRge4M<)9 literal 0 HcmV?d00001 diff --git a/src/qt/icons/superdisk_image.ico b/src/qt/icons/superdisk_image.ico new file mode 100644 index 0000000000000000000000000000000000000000..b8c854fd2346860c41e95d4d51b864ce76a4e774 GIT binary patch literal 9622 zcmeHLF>c&25M0AXj39+wxNvt@rpyoQDz%@GD#$OaGG(5TDs|l5Gwv0sQy5@&M9tlL zkEBRRcSZmcSg%BJXO_bisk6wLT*&pcs9(#s3z5$va&r^!f4>v?rG2-z@&5aJk*^;_ z*6VoxQ{(>V*pC{cmx>Vk)yciaHMF2($1DribzRtOHd!06i}4}TfV*%!@pc~h=bGhz zc#x2?miQ1N#?zDRC|lyek68HacH3J^JhWsy6G+7mn(s8i;(-(SBc2%OOT|MsG(1Br znvVw-EEjKMeLS$VPh(>|#(G1HZRBUp1O9-qpBu4lEUwXSV;Rr!@LXRVzMD63Qt`x~ zFU2zlj7=Fh$w5x*pU*8pt8I2)uo(7wCfUgmaU_Y3PXY<24%*7klyMHH^ zz~jEhy>D)Q$HZG=J#2opc+}kZgMFX4HTu<@BdvJgweKnF&ek*V(1&p~X0dSX@hp}; zR?NLwUW~(YVAy8yEY>iOK35&T+xv+*1&^5Y&|(Y^xq{2*=C!jqay(*vdzMwO*6F>B z+MSMhRMTvY;f%w%rJvC9NsZ^$7yXu=*c5-aPPNz7RM5iP*eT;O#GVP8XQaS*VpPpO=2G- zrl0w!!`HyaJU9nvw1ocDhMxFP=@|H&19)=y=x1FdJmgR6&pFVS@L2_@8^hOQFNL4O z9>d3b4J+mEu%XwBma0!`zyBsk@1NkMCcshPD*U*n$UEj<${(1_XAVAd^`13Qn|~^I zYJmA5N9x9XwVBr%sFDmn#Y({e8h0R#7uc=j;K>J547~}3;+NC literal 0 HcmV?d00001 diff --git a/src/qt/icons/write_active.ico b/src/qt/icons/write_active.ico index dcd758ee6c6a6a76b60aa2fd3163206979f59f7c..babf8c86c0f94585cf9e00cd60d17c682fcf7c34 100644 GIT binary patch literal 6950 zcmeI%zfTlF6u|L!7nE!Gl^~%YdZ7|*Os1kE6o!V9o@!#re*m>1#)9Vcm{?F>O=;2$>C=xYr$|F4WN}d_E&2RZ|NNQAOAe!n*J#jAl=WuWRI3J?Kyi23+;n;W-s7m$ z)vG!Kbp{@92AU&fGz-nfM8AyQP2}O!H~Qsj{I`7H(eGaG-;jYx=8HRsx#lin9&2MA z{dtV(aaihkY?zCBug*Z7fg3Y0a(gek;}?z0UopR3nH%ET`h0)dFWbM6pZ>I5w%6Mq z8^H1LtB)Uh2KIOm`Exvz+^fWMO1zS{F?de-`F>4R^{!oxtLLBL`*t~7uj&lc8F&O4 zxH5~zgGN;b)y;B`Xx`&E=FgGOkF`H&_&@EGpBMW-Gv2V}^^o_&+r@o0e(H>E|33TS zmiuh<6}bPEN#o7xLxXcj@|GIsf(5J6T=*SbhT~Ez)YW;zKewHzx}V3$nDd zB+JXova+%wDJ5B3Ta%5A4cXe-lI`tn+1c5VoU`oi?#llDz8oAJ$l>9ksHz+t9m()VwI~dZ z_;5l7A&9{d4JKqL2t^!`goF%*A@W6SSu$&d!4bh^C=8AWE+IoY*?==!jUThr-~XbGo1&3d79I^tCcID8o}z{9j5bQ~$bdvMQtf-Vom~ Ss)xNNFD~SFxL+`wzxD&9mw}%E literal 9622 zcmeI2J#ND=422mqC{T3CkRe+=cI*wBspsfa6v!cJpi9Rdqf_Ues#kCxO$ZSL(vg** zKfohEOQJ=|{wz{L5Rru}WwjENojfl^9zqbJ*La9F&*y@=QCHeSVlC>^s(Ys;4Kg?lkJc=!~Q%HaW zNPq-#0{uO5sACTNyVNI50^b|NsAgGY~UEF^CPq$0tt|QJ=hy#dvb1fXL*tvKE`? za#S*He!x<|JlTm`W%3jeoylq3#+xezL|HaZ;C{d|`4CV|yAlkq&IZD-Lva+iAj>UL$1A77Ud6k2bzwWe R{{Mdi^JE28smW%lG640NCT;)# diff --git a/src/qt/icons/zip_image.ico b/src/qt/icons/zip_image.ico new file mode 100644 index 0000000000000000000000000000000000000000..82fd868fdf5026584ecdf6a601ad377ddefa294a GIT binary patch literal 9622 zcmeHNJ8s-C6r^DzMv%fTT)6W#0aE4$c9nCa3UUjpOcmr9L5kEVbqF6|PY}4=Vi9JB z;v=58Bt=SE=K~X%rKIJX89x5xg^f8eXXf(Kpx&5|XU4oU##~(u_di}3^BvEwuZR0j zFOB)|%9zb&xc`c{pJ@9AF}MW7@En!7LtI0#Xgh^0UDtKC@B1t~cQM{(3VDwdFT9ri zb0wv3Uw^Y2E%7ey;n7-!+W4T!Sb9LAzoz&omK>>gpYxC-4qosMZR)b*^yPbUGnOTe z*KHh``VihBa`+7KpC1nLPn{S#me-?ra^!&iv3W5*ngfoT&%C!{Jlpy4_w7V4^eYul zKS9Uq$9DhPAlUjJqBA=Rq#Y<{FF<)|>=1dm+Ip3To%wKIu@yT3sHRk;iKF1+@BG(YESK;&P zk^P*@7rZGh=3^~Ba{Vv<{F;!p!Fs&!V&1X8wfWPzAs5SNJY-BN=dk>c6 z>i&M!oU#w8{ec=O$a_n*f9A$((OU`O9fj>{^P~7ve&w0V3;QSi&hVq%cn&S&Ctb3* zaVEEdc+J(iZIToZZHGVp6@Hmhy92gB@6n+q%n0YWzsQ2`Y`wX4?_nG0+yU|)*71kS zbxLu5K%(aR*-n^uuK&64{ub%${ix-do}cv(_tTca;P}ri&-tG<|76a(`ib%%H1&SU z>tpN3df_bcXVNkCowh#zvGi-SnTuoS7qt`bJ!`K2qBiDRe9o-h|ExaWIZ*zH zzS538tl9r$-+j(q=Y9XRhgyBM^Ji_Uc1KQ5U-VKQTJ&|i@)M4`oIb}q=b=@fTq$ju zDCy@swCI<#YxGkdTJ&@MmI0XRKlNh|E&5EcXr<~}eeHqzwMc2|XGwjYHC+EKQ0J37 zFA)o!V&CZ_s~_{V-v8_R(V6G|<}N*p^RuM?9CyX%$5F;JS&x1bVC;(eQ*)jE=ISTs zVATHw`lPQarL{Jt&+p^-Dp53YKRWP-haB(!CD?0`pL3-myz0Gdcassette.label = std::make_unique(); d->cassette.setEmpty(QString(cassette_fname).isEmpty()); - d->cassette.setWriteProtected(cassette_ui_writeprot); + if (QString(cassette_fname).isEmpty()) + d->cassette.setWriteProtected(false); + else if (QString(cassette_fname).left(5) == "wp://") + d->cassette.setWriteProtected(true); + else + d->cassette.setWriteProtected(cassette_ui_writeprot); d->cassette.refresh(); connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) { MediaMenu::ptr->cassetteMenu->popup(pos - QPoint(0, MediaMenu::ptr->cassetteMenu->sizeHint().height())); @@ -658,7 +663,12 @@ MachineStatus::refresh(QStatusBar *sbar) } d->fdd[i].label = std::make_unique(); d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty()); - d->fdd[i].setWriteProtected(ui_writeprot[i]); + if (QString(floppyfns[i]).isEmpty()) + d->fdd[i].setWriteProtected(false); + else if (QString(floppyfns[i]).left(5) == "wp://") + d->fdd[i].setWriteProtected(true); + else + d->fdd[i].setWriteProtected(ui_writeprot[i]); d->fdd[i].setActive(false); d->fdd[i].setWriteActive(false); d->fdd[i].refresh(); @@ -693,7 +703,12 @@ MachineStatus::refresh(QStatusBar *sbar) iterateZIP([this, sbar](int i) { d->zip[i].label = std::make_unique(); d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty()); - d->zip[i].setWriteProtected(zip_drives[i].read_only); + if (QString(zip_drives[i].image_path).isEmpty()) + d->zip[i].setWriteProtected(false); + else if (QString(zip_drives[i].image_path).left(5) == "wp://") + d->zip[i].setWriteProtected(true); + else + d->zip[i].setWriteProtected(zip_drives[i].read_only); d->zip[i].setActive(false); d->zip[i].setWriteActive(false); d->zip[i].refresh(); @@ -711,7 +726,12 @@ MachineStatus::refresh(QStatusBar *sbar) iterateMO([this, sbar](int i) { d->mo[i].label = std::make_unique(); d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty()); - d->mo[i].setWriteProtected(mo_drives[i].read_only); + if (QString(zip_drives[i].image_path).isEmpty()) + d->mo[i].setWriteProtected(false); + else if (QString(zip_drives[i].image_path).left(5) == "wp://") + d->mo[i].setWriteProtected(true); + else + d->mo[i].setWriteProtected(zip_drives[i].read_only); d->mo[i].setActive(false); d->mo[i].setWriteActive(false); d->mo[i].refresh(); diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 5892c55cd..74d596866 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -21,6 +21,9 @@ #include #include #include "qt_mediahistorymanager.hpp" +#ifdef Q_OS_WINDOWS +#include +#endif extern "C" { #include <86box/timer.h> @@ -205,6 +208,8 @@ MediaHistoryManager::initialDeduplication() break; } deduplicateList(device_history, QVector(1, current_image)); + device_history = removeMissingImages(device_history); + device_history = pathAdjustFull(device_history); // Fill in missing, if any int missing = MAX_PREV_IMAGES - device_history.size(); if (missing) { @@ -213,6 +218,7 @@ MediaHistoryManager::initialDeduplication() } } setHistoryListForDeviceIndex(device_index, device_type, device_history); + serializeImageHistoryType(device_type); } } } @@ -343,24 +349,42 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) char temp[MAX_IMAGE_PATH_LEN * 2] = { 0 }; - if (path_abs(checked_path.toUtf8().data())) { - if (checked_path.length() > (MAX_IMAGE_PATH_LEN - 1)) - fatal("removeMissingImages(): checked_path.length() > %i\n", MAX_IMAGE_PATH_LEN - 1); - else - snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", checked_path.toUtf8().constData()); + if (checked_path.left(8) == "ioctl://") { + strncpy(temp, checked_path.toUtf8().data(), sizeof(temp)); + temp[sizeof(temp) - 1] = '\0'; } else { - if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + checked_path.length()) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1); + QString path_only; + if (checked_path.left(5) == "wp://") + path_only = checked_path.right(checked_path.length() - 5); else - snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, - path_get_slash(usr_path), checked_path.toUtf8().constData()); + path_only = checked_path; + + if (path_abs(path_only.toUtf8().data())) { + if (path_only.length() > (MAX_IMAGE_PATH_LEN - 1)) + fatal("removeMissingImages(): path_only.length() > %i\n", MAX_IMAGE_PATH_LEN - 1); + else + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", path_only.toUtf8().constData()); + } else { + if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + path_only.length()) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1); + else + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), path_only.toUtf8().constData()); + } + path_normalize(temp); } - path_normalize(temp); QString qstr = QString::fromUtf8(temp); QFileInfo new_fi(qstr); - if ((new_fi.filePath().left(8) != "ioctl://") && !new_fi.exists()) { + bool file_exists = new_fi.exists(); + +#ifdef Q_OS_WINDOWS + if (new_fi.filePath().left(8) == "ioctl://") + file_exists = (GetDriveType(new_fi.filePath().right(2).toUtf8().data()) == DRIVE_CDROM); +#endif + + if (!file_exists) { qWarning("Image file %s does not exist - removing from history", qPrintable(new_fi.filePath())); checked_path = ""; } diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index c9d658fb2..cf14d7826 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -69,9 +69,12 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_mediahistorymanager.hpp" #include "qt_mediamenu.hpp" +#include "qt_iconindicators.hpp" std::shared_ptr MediaMenu::ptr; +static QSize pixmap_size(16, 16); + MediaMenu::MediaMenu(QWidget *parent) : QObject(parent) { @@ -86,27 +89,28 @@ MediaMenu::refresh(QMenu *parentMenu) if (MachineStatus::hasCassette()) { cassetteMenu = parentMenu->addMenu(""); - cassetteMenu->addAction(tr("&New image..."), [this]() { cassetteNewImage(); }); + QIcon img_icon = QIcon(":/settings/qt/icons/cassette_image.ico"); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this]() { cassetteNewImage(); }); cassetteMenu->addSeparator(); - cassetteMenu->addAction(tr("&Existing image..."), [this]() { cassetteSelectImage(false); }); - cassetteMenu->addAction(tr("Existing image (&Write-protected)..."), [this]() { cassetteSelectImage(true); }); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this]() { cassetteSelectImage(false); }); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this]() { cassetteSelectImage(true); }); cassetteMenu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cassetteImageHistoryPos[slot] = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("Image %1").arg(slot), [this, slot]() { cassetteMenuSelect(slot); })->setCheckable(false); + cassetteMenu->addAction(img_icon, tr("Image %1").arg(slot), [this, slot]() { cassetteMenuSelect(slot); })->setCheckable(false); } cassetteMenu->addSeparator(); cassetteRecordPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Record"), [this] { pc_cas_set_mode(cassette, 1); cassetteUpdateMenu(); })->setCheckable(true); + cassetteMenu->addAction(QIcon(":/settings/qt/icons/record.ico"), tr("&Record"), [this] { pc_cas_set_mode(cassette, 1); cassetteUpdateMenu(); })->setCheckable(true); cassettePlayPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Play"), [this] { pc_cas_set_mode(cassette, 0); cassetteUpdateMenu(); })->setCheckable(true); + cassetteMenu->addAction(QIcon(":/menuicons/qt/icons/run.ico"), tr("&Play"), [this] { pc_cas_set_mode(cassette, 0); cassetteUpdateMenu(); })->setCheckable(true); cassetteRewindPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Rewind to the beginning"), [] { pc_cas_rewind(cassette); }); + cassetteMenu->addAction(QIcon(":/settings/qt/icons/rewind.ico"), tr("&Rewind to the beginning"), [] { pc_cas_rewind(cassette); }); cassetteFastFwdPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Fast forward to the end"), [] { pc_cas_append(cassette); }); + cassetteMenu->addAction(QIcon(":/settings/qt/icons/fast_forward.ico"), tr("&Fast forward to the end"), [] { pc_cas_append(cassette); }); cassetteMenu->addSeparator(); cassetteEjectPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("E&ject"), [this]() { cassetteEject(); }); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this]() { cassetteEject(); }); cassetteUpdateMenu(); } @@ -114,15 +118,16 @@ MediaMenu::refresh(QMenu *parentMenu) if (machine_has_cartridge(machine)) { for (int i = 0; i < 2; i++) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); + QIcon img_icon = QIcon(":/settings/qt/icons/cartridge_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cartridgeImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { cartridgeMenuSelect(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { cartridgeMenuSelect(i, slot); })->setCheckable(false); } menu->addSeparator(); cartridgeEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { cartridgeEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { cartridgeEject(i); }); cartridgeMenus[i] = menu; cartridgeUpdateMenu(i); } @@ -131,21 +136,23 @@ MediaMenu::refresh(QMenu *parentMenu) floppyMenus.clear(); MachineStatus::iterateFDD([this, parentMenu](int i) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&New image..."), [this, i]() { floppyNewImage(i); }); + QIcon img_icon = fdd_is_525(i) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : + QIcon(":/settings/qt/icons/floppy_35_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { floppyNewImage(i); }); menu->addSeparator(); - menu->addAction(tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); - menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { floppySelectImage(i, true); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this, i]() { floppySelectImage(i, true); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { floppyImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { floppyMenuSelect(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { floppyMenuSelect(i, slot); })->setCheckable(false); } menu->addSeparator(); floppyExportPos = menu->children().count(); - menu->addAction(tr("E&xport to 86F..."), [this, i]() { floppyExportTo86f(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Export), tr("E&xport to 86F..."), [this, i]() { floppyExportTo86f(i); }); menu->addSeparator(); floppyEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { floppyEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { floppyEject(i); }); floppyMenus[i] = menu; floppyUpdateMenu(i); }); @@ -156,8 +163,8 @@ MediaMenu::refresh(QMenu *parentMenu) cdromMutePos = menu->children().count(); menu->addAction(QIcon(":/settings/qt/icons/cdrom_mute.ico"), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); - menu->addAction(QIcon(":/settings/qt/icons/cdrom_image.ico"), tr("&Image..."), [this, i]() { cdromMount(i, 0, nullptr); })->setCheckable(false); - menu->addAction(QIcon(":/settings/qt/icons/cdrom_folder.ico"), tr("&Folder..."), [this, i]() { cdromMount(i, 1, nullptr); })->setCheckable(false); + menu->addAction(getIconWithIndicator(QIcon(":/settings/qt/icons/cdrom_image.ico"), pixmap_size, QIcon::Normal, Browse), tr("&Image..."), [this, i]() { cdromMount(i, 0, nullptr); })->setCheckable(false); + menu->addAction(getIconWithIndicator(QIcon(":/settings/qt/icons/cdrom_folder.ico"), pixmap_size, QIcon::Normal, Browse), tr("&Folder..."), [this, i]() { cdromMount(i, 1, nullptr); })->setCheckable(false); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cdromImageHistoryPos[slot] = menu->children().count(); @@ -183,18 +190,19 @@ MediaMenu::refresh(QMenu *parentMenu) zipMenus.clear(); MachineStatus::iterateZIP([this, parentMenu](int i) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&New image..."), [this, i]() { zipNewImage(i); }); + QIcon img_icon = QIcon(":/settings/qt/icons/zip_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { zipNewImage(i); }); menu->addSeparator(); - menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); - menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { zipSelectImage(i, true); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this, i]() { zipSelectImage(i, true); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { zipImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { zipReload(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { zipReload(i, slot); })->setCheckable(false); } menu->addSeparator(); zipEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { zipEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { zipEject(i); }); zipMenus[i] = menu; zipUpdateMenu(i); }); @@ -202,18 +210,19 @@ MediaMenu::refresh(QMenu *parentMenu) moMenus.clear(); MachineStatus::iterateMO([this, parentMenu](int i) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&New image..."), [this, i]() { moNewImage(i); }); + QIcon img_icon = QIcon(":/settings/qt/icons/mo_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { moNewImage(i); }); menu->addSeparator(); - menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); - menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { moSelectImage(i, true); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this, i]() { moSelectImage(i, true); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { moImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { moReload(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { moReload(i, slot); })->setCheckable(false); } menu->addSeparator(); moEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { moEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { moEject(i); }); moMenus[i] = menu; moUpdateMenu(i); }); @@ -277,6 +286,12 @@ MediaMenu::cassetteMount(const QString &filename, bool wp) if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + cassette_ui_writeprot = 1; + else if (cassette_ui_writeprot) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + strncpy(cassette_fname, filenameBytes.data(), sizeof(cassette_fname) - 1); pc_cas_set_fname(cassette, cassette_fname); } @@ -444,11 +459,18 @@ MediaMenu::floppyMount(int i, const QString &filename, bool wp) ui_writeprot[i] = wp ? 1 : 0; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + ui_writeprot[i] = 1; + else if (ui_writeprot[i]) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + fdd_load(i, filenameBytes.data()); - } + mhm.addImageToHistory(i, ui::MediaType::Floppy, previous_image.filePath(), QString(filenameBytes)); + } else + mhm.addImageToHistory(i, ui::MediaType::Floppy, previous_image.filePath(), filename); ui_sb_update_icon_state(SB_FLOPPY | i, filename.isEmpty() ? 1 : 0); ui_sb_update_icon_wp(SB_FLOPPY | i, ui_writeprot[i]); - mhm.addImageToHistory(i, ui::MediaType::Floppy, previous_image.filePath(), filename); floppyUpdateMenu(i); ui_sb_update_tip(SB_FLOPPY | i); config_save(); @@ -569,7 +591,7 @@ MediaMenu::cdromMount(int i, int dir, const QString &arg) QFileInfo fi(cdrom[i].image_path); if (dir > 1) - filename = QString::asprintf(R"(ioctl://%s)", arg.toStdString().c_str()); + filename = QString::asprintf(R"(ioctl://%s)", arg.toUtf8().data()); else if (dir == 1) filename = QFileDialog::getExistingDirectory(parentWidget); else { @@ -641,8 +663,18 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = cassetteMenu; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[cassetteImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = QIcon(":/settings/qt/icons/cassette_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; case ui::MediaType::Cartridge: if (!machine_has_cartridge(machine)) @@ -659,8 +691,19 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = floppyMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = fdd_is_525(index) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : + QIcon(":/settings/qt/icons/floppy_35_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; case ui::MediaType::Optical: if (!cdromMenus.contains(index)) @@ -688,8 +731,18 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = zipMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[zipImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = QIcon(":/settings/qt/icons/mo_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; case ui::MediaType::Mo: if (!moMenus.contains(index)) @@ -697,8 +750,18 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = moMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[moImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = QIcon(":/settings/qt/icons/mo_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; } @@ -749,9 +812,12 @@ MediaMenu::cdromUpdateMenu(int i) menu_item_name = name.isEmpty() ? QString() : fi.fileName(); name2 = name; - menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); + if (name.isEmpty()) + menu_icon = QIcon(":/settings/qt/icons/cdrom.ico"); + else + menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); } - ejectMenu->setIcon(menu_icon); + ejectMenu->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, Eject)); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(menu_item_name)); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) @@ -812,6 +878,12 @@ MediaMenu::zipMount(int i, const QString &filename, bool wp) zip_drives[i].read_only = wp; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + zip_drives[i].read_only = 1; + else if (zip_drives[i].read_only) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + zip_load(dev, filenameBytes.data(), 1); /* Signal media change to the emulated machine. */ @@ -951,6 +1023,12 @@ MediaMenu::moMount(int i, const QString &filename, bool wp) mo_drives[i].read_only = wp; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + mo_drives[i].read_only = 1; + else if (mo_drives[i].read_only) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + mo_load(dev, filenameBytes.data(), 1); /* Signal media change to the emulated machine. */ diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index 9291892b5..f0ea8d945 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -1,6 +1,9 @@ + qt/icons/browse.ico qt/icons/cartridge.ico + qt/icons/cartridge_image.ico + qt/icons/cassette_image.ico qt/icons/cassette.ico qt/icons/cdrom.ico qt/icons/cdrom_disabled.ico @@ -10,22 +13,35 @@ qt/icons/cdrom_folder.ico qt/icons/cdrom_host.ico qt/icons/display.ico + qt/icons/eject.ico + qt/icons/export.ico + qt/icons/fast_forward.ico qt/icons/floppy_35.ico + qt/icons/floppy_35_image.ico qt/icons/floppy_525.ico + qt/icons/floppy_525_image.ico qt/icons/floppy_and_cdrom_drives.ico qt/icons/floppy_disabled.ico qt/icons/hard_disk.ico qt/icons/input_devices.ico qt/icons/machine.ico qt/icons/mo.ico + qt/icons/mo_image.ico qt/icons/mo_disabled.ico qt/icons/network.ico + qt/icons/new.ico qt/icons/other_peripherals.ico qt/icons/other_removable_devices.ico qt/icons/ports.ico + qt/icons/record.ico + qt/icons/rewind.ico qt/icons/sound.ico qt/icons/storage_controllers.ico + qt/icons/superdisk.ico + qt/icons/superdisk_image.ico + qt/icons/superdisk_disabled.ico qt/icons/zip.ico + qt/icons/zip_image.ico qt/icons/zip_disabled.ico qt/icons/active.ico qt/icons/write_protected.ico