summaryrefslogblamecommitdiffstatshomepage
path: root/src/frontend/mame/ui/floppycntrl.cpp
blob: a8ffc764a4bf204378ea3426fe84e6f86adc54b4 (plain) (tree)


















                                                                            
                                                                                                                                                                                                    
































































                                                                                                 
                                                                            






                                                                                                                     
                                                                                                                   
























                                                                                  
                                                                                                                                                        



































                                                                                                                
                                                                                                                                                          











                                                       
 
// 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<floppy_image_device *>(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<floppy_image_device *>(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<floppy_image_device *>(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_menu_select_rw>(ui(), container, can_in_place, &submenu_result));
	state = SELECT_RW;
}

void ui_menu_control_floppy_image::handle()
{
	floppy_image_device *fd = static_cast<floppy_image_device *>(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_menu_select_format>(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_menu_file_create>(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();
	}
}