diff options
Diffstat (limited to 'src/frontend/mame/ui/floppycntrl.cpp')
-rw-r--r-- | src/frontend/mame/ui/floppycntrl.cpp | 202 |
1 files changed, 116 insertions, 86 deletions
diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp index e97151ebc4c..3f6f9bdfb61 100644 --- a/src/frontend/mame/ui/floppycntrl.cpp +++ b/src/frontend/mame/ui/floppycntrl.cpp @@ -12,8 +12,13 @@ #include "ui/filecreate.h" #include "ui/floppycntrl.h" +#include "formats/flopimg.h" +#include "formats/fsmgr.h" + #include "zippath.h" +#include <tuple> + namespace ui { @@ -30,11 +35,6 @@ menu_control_floppy_image::menu_control_floppy_image(mame_ui_manager &mui, rende input_filename(), output_filename() { - int fcnt = 0; - for(const floppy_image_format_t *i = fd.get_formats(); i; i = i->next) - fcnt++; - - format_array = std::make_unique<floppy_image_format_t * []>(fcnt); } menu_control_floppy_image::~menu_control_floppy_image() @@ -43,24 +43,28 @@ menu_control_floppy_image::~menu_control_floppy_image() void menu_control_floppy_image::do_load_create() { - if(input_filename.compare("")==0) { - image_init_result err = fd.create(output_filename, nullptr, nullptr); - if (err != image_init_result::PASS) { - machine().popmessage("Error: %s", fd.error()); + if(input_filename.empty()) { + auto [err, message] = fd.create(output_filename, nullptr, nullptr); + if (err) { + machine().popmessage(_("Error creating floppy image: %1$s"), !message.empty() ? message : err.message()); return; } if (create_fs) { // HACK: ensure the floppy_image structure is created since device_image_interface may not otherwise do so during "init phase" - err = fd.finish_load(); - if (err == image_init_result::PASS) - fd.init_fs(create_fs); + err = fd.finish_load().first; + if (!err) { + fs::meta_data meta; + fd.init_fs(create_fs, meta); + } } } else { - image_init_result err = fd.load(input_filename); - if ((err == image_init_result::PASS) && (output_filename.compare("") != 0)) - err = fd.reopen_for_write(output_filename) ? image_init_result::FAIL : image_init_result::PASS; - if (err != image_init_result::PASS) { - machine().popmessage("Error: %s", fd.error()); + auto [err, message] = fd.load(input_filename); + if (!err && !output_filename.empty()) { + message.clear(); + err = fd.reopen_for_write(output_filename); + } + if (err) { + machine().popmessage(_("Error opening floppy image: %1$s"), !message.empty() ? message : err.message()); return; } } @@ -70,123 +74,149 @@ void menu_control_floppy_image::do_load_create() void menu_control_floppy_image::hook_load(const std::string &filename) { + std::error_condition err; input_filename = filename; - input_format = static_cast<floppy_image_device &>(m_image).identify(filename); + std::tie(err, input_format) = static_cast<floppy_image_device &>(m_image).identify(filename); if (!input_format) { - machine().popmessage("Error: %s\n", m_image.error()); + machine().popmessage("Error: %s", err.message()); stack_pop(); - 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, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); - if(filerr == osd_file::error::NONE) - tmp_file.reset(); - else - can_in_place = false; + else + { + bool can_in_place = input_format->supports_save(); + if (can_in_place) + { + std::string tmp_path; + util::core_file::ptr tmp_file; + // attempt to open the file for writing but *without* create + std::error_condition const filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path); + if(!filerr) + tmp_file.reset(); + else + can_in_place = false; + } + menu::stack_push<menu_select_rw>( + ui(), + container(), + can_in_place, + [this] (menu_select_rw::result result) + { + switch (result) + { + case menu_select_rw::result::READONLY: + do_load_create(); + fd.setup_write(nullptr); + stack_pop(); + break; + + case menu_select_rw::result::READWRITE: + output_format = input_format; + do_load_create(); + stack_pop(); + break; + + case menu_select_rw::result::WRITE_DIFF: + machine().popmessage("Sorry, diffs are not supported yet\n"); + stack_pop(); + break; + + case menu_select_rw::result::WRITE_OTHER: + menu::stack_push<menu_file_create>(ui(), container(), &m_image, m_current_directory, m_current_file, m_create_ok); + m_state = CHECK_CREATE; + break; + + case menu_select_rw::result::INVALID: + m_state = START_FILE; + break; + } + }); } - m_submenu_result.rw = menu_select_rw::result::INVALID; - menu::stack_push<menu_select_rw>(ui(), container(), can_in_place, m_submenu_result.rw); - m_state = SELECT_RW; } -void menu_control_floppy_image::handle() +bool menu_control_floppy_image::can_format(const floppy_image_device::fs_info &fs) +{ + return !fs.m_manager || fs.m_manager->can_format(); +} + +void menu_control_floppy_image::menu_activated() { switch (m_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) { + std::vector<const floppy_image_format_t *> format_array; + for(const floppy_image_format_t *i : fd.get_formats()) { if(!i->supports_save()) continue; if (i->extension_matches(m_current_file.c_str())) - format_array[total_usable++] = i; + format_array.push_back(i); } - ext_match = total_usable; - for(floppy_image_format_t *i = fif_list; i; i = i->next) { + int ext_match = format_array.size(); + for(const floppy_image_format_t *i : fd.get_formats()) { if(!i->supports_save()) continue; if (!i->extension_matches(m_current_file.c_str())) - format_array[total_usable++] = i; + format_array.push_back(i); } - m_submenu_result.i = -1; - menu::stack_push<menu_select_format>(ui(), container(), format_array.get(), ext_match, total_usable, &m_submenu_result.i); + output_format = nullptr; + menu::stack_push<menu_select_format>(ui(), container(), format_array, ext_match, &output_format); m_state = SELECT_FORMAT; break; } case SELECT_FORMAT: - if(m_submenu_result.i == -1) { + if(!output_format) { m_state = START_FILE; - handle(); + menu_activated(); } else { - const auto &fs = fd.get_fs(); + // get all formatable file systems + std::vector<std::reference_wrapper<const floppy_image_device::fs_info>> fs; + for (const auto &this_fs : fd.get_fs()) { + if (can_format(this_fs)) + fs.emplace_back(std::ref(this_fs)); + } + output_filename = util::zippath_combine(m_current_directory, m_current_file); - output_format = format_array[m_submenu_result.i]; if(fs.size() == 1) { - create_fs = &fs[0]; + create_fs = &(fs[0].get()); do_load_create(); stack_pop(); } else { m_submenu_result.i = -1; - menu::stack_push<menu_select_floppy_init>(ui(), container(), fs, &m_submenu_result.i); + menu::stack_push<menu_select_floppy_init>(ui(), container(), std::move(fs), &m_submenu_result.i); m_state = SELECT_INIT; } } break; case SELECT_INIT: - if(m_submenu_result.i == -1) { - m_state = START_FILE; - handle(); - } else { - create_fs = &fd.get_fs()[m_submenu_result.i]; - do_load_create(); - stack_pop(); + // figure out which (if any) create file system was selected + create_fs = nullptr; + if(m_submenu_result.i >= 0) { + int i = 0; + for (const auto &this_fs : fd.get_fs()) { + if (can_format(this_fs)) { + if (i == m_submenu_result.i) { + create_fs = &this_fs; + break; + } + i++; + } + } } - break; - - case SELECT_RW: - switch(m_submenu_result.rw) { - case menu_select_rw::result::READONLY: - do_load_create(); - fd.setup_write(nullptr); - stack_pop(); - break; - case menu_select_rw::result::READWRITE: - output_format = input_format; + if(!create_fs) { + m_state = START_FILE; + menu_activated(); + } else { do_load_create(); stack_pop(); - break; - - case menu_select_rw::result::WRITE_DIFF: - machine().popmessage("Sorry, diffs are not supported yet\n"); - stack_pop(); - break; - - case menu_select_rw::result::WRITE_OTHER: - menu::stack_push<menu_file_create>(ui(), container(), &m_image, m_current_directory, m_current_file, m_create_ok); - m_state = CHECK_CREATE; - break; - - case menu_select_rw::result::INVALID: - m_state = START_FILE; - break; } break; default: - menu_control_device_image::handle(); + menu_control_device_image::menu_activated(); } } |