// license:BSD-3-Clause // copyright-holders:Olivier Galibert /*************************************************************************** ui/floppycntrl.cpp ***************************************************************************/ #include "emu.h" #include "zippath.h" #include "ui/menu.h" #include "ui/imgcntrl.h" #include "ui/filesel.h" #include "ui/floppycntrl.h" /*************************************************************************** IMPLEMENTATION ***************************************************************************/ ui_menu_control_floppy_image::ui_menu_control_floppy_image(mame_ui_manager &mui, render_container *container, device_image_interface *_image) : ui_menu_control_device_image(mui, container, _image) { floppy_image_device *fd = static_cast(image); const floppy_image_format_t *fif_list = fd->get_formats(); int fcnt = 0; for(const floppy_image_format_t *i = fif_list; i; i = i->next) fcnt++; format_array = global_alloc_array(floppy_image_format_t *, fcnt); input_format = output_format = nullptr; input_filename = output_filename = ""; } ui_menu_control_floppy_image::~ui_menu_control_floppy_image() { global_free_array(format_array); } void ui_menu_control_floppy_image::do_load_create() { floppy_image_device *fd = static_cast(image); if(input_filename.compare("")==0) { int err = fd->create(output_filename.c_str(), nullptr, nullptr); if (err != 0) { machine().popmessage("Error: %s", fd->error()); return; } fd->setup_write(output_format); } else { int err = fd->load(input_filename.c_str()); if (!err && output_filename.compare("") != 0) err = fd->reopen_for_write(output_filename.c_str()); if(err != 0) { machine().popmessage("Error: %s", fd->error()); return; } if(output_format) fd->setup_write(output_format); } } void ui_menu_control_floppy_image::hook_load(std::string filename, bool softlist) { if (softlist) { machine().popmessage("When loaded from software list, the disk is Read-only.\n"); image->load(filename.c_str()); ui_menu::stack_pop(machine()); return; } input_filename = filename; input_format = static_cast(image)->identify(filename); if (!input_format) { machine().popmessage("Error: %s\n", image->error()); ui_menu::stack_pop(machine()); return; } bool can_in_place = input_format->supports_save(); if(can_in_place) { osd_file::error filerr; std::string tmp_path; util::core_file::ptr tmp_file; // attempt to open the file for writing but *without* create filerr = util::zippath_fopen(filename.c_str(), OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); if(filerr == osd_file::error::NONE) tmp_file.reset(); else can_in_place = false; } submenu_result = -1; ui_menu::stack_push(global_alloc_clear(ui(), container, can_in_place, &submenu_result)); state = SELECT_RW; } void ui_menu_control_floppy_image::handle() { floppy_image_device *fd = static_cast(image); switch (state) { case DO_CREATE: { floppy_image_format_t *fif_list = fd->get_formats(); int ext_match; int total_usable = 0; for(floppy_image_format_t *i = fif_list; i; i = i->next) { if(!i->supports_save()) continue; if (i->extension_matches(current_file.c_str())) format_array[total_usable++] = i; } ext_match = total_usable; for(floppy_image_format_t *i = fif_list; i; i = i->next) { if(!i->supports_save()) continue; if (!i->extension_matches(current_file.c_str())) format_array[total_usable++] = i; } submenu_result = -1; ui_menu::stack_push(global_alloc_clear(ui(), container, format_array, ext_match, total_usable, &submenu_result)); state = SELECT_FORMAT; break; } case SELECT_FORMAT: if(submenu_result == -1) { state = START_FILE; handle(); } else { util::zippath_combine(output_filename, current_directory.c_str(), current_file.c_str()); output_format = format_array[submenu_result]; do_load_create(); ui_menu::stack_pop(machine()); } break; case SELECT_RW: switch(submenu_result) { case ui_menu_select_rw::READONLY: do_load_create(); ui_menu::stack_pop(machine()); break; case ui_menu_select_rw::READWRITE: output_format = input_format; do_load_create(); ui_menu::stack_pop(machine()); break; case ui_menu_select_rw::WRITE_DIFF: machine().popmessage("Sorry, diffs are not supported yet\n"); ui_menu::stack_pop(machine()); break; case ui_menu_select_rw::WRITE_OTHER: ui_menu::stack_push(global_alloc_clear(ui(), container, image, current_directory, current_file, &create_ok)); state = CHECK_CREATE; break; case -1: state = START_FILE; break; } break; default: ui_menu_control_device_image::handle(); } }