diff options
Diffstat (limited to 'src/emu/diimage.h')
-rw-r--r-- | src/emu/diimage.h | 224 |
1 files changed, 81 insertions, 143 deletions
diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 67d20c43402..aa9c991c955 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -17,11 +17,13 @@ #ifndef MAME_EMU_DIIMAGE_H #define MAME_EMU_DIIMAGE_H +#include "notifier.h" #include "utilfwd.h" #include <memory> #include <string> #include <system_error> +#include <utility> #include <vector> @@ -29,39 +31,15 @@ // TYPE DEFINITIONS //************************************************************************** -enum iodevice_t -{ - /* List of all supported devices. Refer to the device by these names only */ - IO_UNKNOWN, - IO_CARTSLOT, /* 1 - Cartridge Port, as found on most console and on some computers */ - IO_FLOPPY, /* 2 - Floppy Disk unit */ - IO_HARDDISK, /* 3 - Hard Disk unit */ - IO_CYLINDER, /* 4 - Magnetically-Coated Cylinder */ - IO_CASSETTE, /* 5 - Cassette Recorder (common on early home computers) */ - IO_PUNCHCARD, /* 6 - Card Puncher/Reader */ - IO_PUNCHTAPE, /* 7 - Tape Puncher/Reader (reels instead of punchcards) */ - IO_PRINTER, /* 8 - Printer device */ - IO_SERIAL, /* 9 - Generic Serial Port */ - IO_PARALLEL, /* 10 - Generic Parallel Port */ - IO_SNAPSHOT, /* 11 - Complete 'snapshot' of the state of the computer */ - IO_QUICKLOAD, /* 12 - Allow to load program/data into memory, without matching any actual device */ - IO_MEMCARD, /* 13 - Memory card */ - IO_CDROM, /* 14 - optical CD-ROM disc */ - IO_MAGTAPE, /* 15 - Magnetic tape */ - IO_ROM, /* 16 - Individual ROM image - the Amstrad CPC has a few applications that were sold on 16kB ROMs */ - IO_MIDIIN, /* 17 - MIDI In port */ - IO_MIDIOUT, /* 18 - MIDI Out port */ - IO_PICTURE, /* 19 - A single-frame image */ - IO_VIDEO, /* 20 - A video file */ - IO_COUNT /* 21 - Total Number of IO_devices for searching */ -}; - enum class image_error : int { INTERNAL = 1, UNSUPPORTED, INVALIDIMAGE, + INVALIDLENGTH, ALREADYOPEN, + NOSOFTWARE, + BADSOFTWARE, UNSPECIFIED }; @@ -69,13 +47,6 @@ const std::error_category &image_category() noexcept; inline std::error_condition make_error_condition(image_error e) noexcept { return std::error_condition(int(e), image_category()); } namespace std { template <> struct is_error_condition_enum<image_error> : public std::true_type { }; } -struct image_device_type_info -{ - iodevice_t m_type; - const char *m_name; - const char *m_shortname; -}; - class image_device_format { public: @@ -95,66 +66,56 @@ private: }; -enum class image_init_result { PASS, FAIL }; -enum class image_verify_result { PASS, FAIL }; - -//************************************************************************** -// MACROS -//************************************************************************** - -#define DEVICE_IMAGE_LOAD_MEMBER(_name) image_init_result _name(device_image_interface &image) -#define DECLARE_DEVICE_IMAGE_LOAD_MEMBER(_name) DEVICE_IMAGE_LOAD_MEMBER(_name) - -#define DEVICE_IMAGE_UNLOAD_MEMBER(_name) void _name(device_image_interface &image) -#define DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(_name) DEVICE_IMAGE_UNLOAD_MEMBER(_name) - - // ======================> device_image_interface // class representing interface-specific live image class device_image_interface : public device_interface { public: - typedef device_delegate<image_init_result (device_image_interface &)> load_delegate; - typedef device_delegate<void (device_image_interface &)> unload_delegate; + enum class media_change_event + { + LOADED, + UNLOADED + }; - typedef std::vector<std::unique_ptr<image_device_format>> formatlist_type; + using formatlist_type = std::vector<std::unique_ptr<image_device_format> >; // construction/destruction device_image_interface(const machine_config &mconfig, device_t &device); virtual ~device_image_interface(); - static const char *device_typename(iodevice_t type); - static const char *device_brieftypename(iodevice_t type); - static iodevice_t device_typeid(const char *name); - - virtual image_init_result call_load() { return image_init_result::PASS; } - virtual image_init_result call_create(int format_type, util::option_resolution *format_options) { return image_init_result::PASS; } + virtual std::pair<std::error_condition, std::string> call_load() { return std::make_pair(std::error_condition(), std::string()); } + virtual std::pair<std::error_condition, std::string> call_create(int format_type, util::option_resolution *format_options) { return std::make_pair(std::error_condition(), std::string()); } virtual void call_unload() { } virtual std::string call_display() { return std::string(); } virtual u32 unhashed_header_length() const noexcept { return 0; } virtual bool core_opens_image_file() const noexcept { return true; } - virtual iodevice_t image_type() const noexcept = 0; + virtual bool image_is_chd_type() const noexcept { return false; } virtual bool is_readable() const noexcept = 0; virtual bool is_writeable() const noexcept = 0; virtual bool is_creatable() const noexcept = 0; - virtual bool must_be_loaded() const noexcept = 0; virtual bool is_reset_on_load() const noexcept = 0; - virtual bool support_command_line_image_creation() const noexcept; + virtual bool support_command_line_image_creation() const noexcept { return false; } virtual const char *image_interface() const noexcept { return nullptr; } virtual const char *file_extensions() const noexcept = 0; virtual const util::option_guide &create_option_guide() const; - virtual const char *custom_instance_name() const noexcept { return nullptr; } - virtual const char *custom_brief_instance_name() const noexcept { return nullptr; } + virtual const char *image_type_name() const noexcept = 0; + virtual const char *image_brief_type_name() const noexcept = 0; + + // Set block device image regions for arcade systems + void add_region(std::string name, bool is_default = false); + bool has_preset_images() const; + bool has_preset_images_selection() const; + std::vector<std::string> preset_images_list() const; + int current_preset_image_id() const; + void switch_preset_image(int id); + chd_file *current_preset_image_chd() const; + void check_preset_images(); const image_device_format *device_get_indexed_creatable_format(int index) const noexcept { return (index < m_formatlist.size()) ? m_formatlist.at(index).get() : nullptr; } - const image_device_format *device_get_named_creatable_format(const std::string &format_name) noexcept; + const image_device_format *device_get_named_creatable_format(std::string_view format_name) const noexcept; const util::option_guide &device_get_creation_option_guide() const { return create_option_guide(); } - std::string_view error(); - void seterror(std::error_condition err, const char *message); - void message(const char *format, ...) ATTR_PRINTF(2,3); - bool exists() const noexcept { return !m_image_name.empty(); } // get image file path/name @@ -165,9 +126,15 @@ public: bool is_filetype(std::string_view candidate_filetype) const; bool is_open() const noexcept { return bool(m_file); } - util::core_file &image_core_file() const noexcept { return *m_file; } + util::core_file &image_core_file() const noexcept { assert(is_open()); return *m_file; } bool is_readonly() const noexcept { return m_readonly; } + u32 sequence_counter() const { return m_sequence_counter; } // Increments on media load/unload/etc + util::notifier_subscription add_media_change_notifier(delegate<void (media_change_event)> &&n); + template <typename T> + util::notifier_subscription add_media_change_notifier(T &&n) + { return add_media_change_notifier(delegate<void (media_change_event)>(std::forward<T>(n))); } + // image file I/O wrappers // TODO: move away from using these and let implementations use the I/O interface directly // FIXME: don't swallow errors @@ -181,15 +148,13 @@ public: u32 fread(void *buffer, u32 length) { check_for_file(); - size_t actual; - m_file->read(buffer, length, actual); + auto const [err, actual] = read(*m_file, buffer, length); return actual; } u32 fwrite(const void *buffer, u32 length) { check_for_file(); - size_t actual; - m_file->write(buffer, length, actual); + auto const [err, actual] = write(*m_file, buffer, length); return actual; } std::error_condition fseek(s64 offset, int whence) @@ -204,32 +169,6 @@ public: m_file->tell(result); return result; } - int fgetc() - { - char ch; - if (fread(&ch, 1) != 1) - ch = '\0'; - return ch; - } - char *fgets(char *buffer, u32 length) - { - check_for_file(); - return m_file->gets(buffer, length); - } - bool image_feof() - { - check_for_file(); - return m_file->eof(); - } - const void *ptr() - { - check_for_file(); - return m_file->buffer(); - } - - // allocate and read into buffers - u32 fread(std::unique_ptr<u8 []> &ptr, u32 length) { ptr = std::make_unique<u8 []>(length); return fread(ptr.get(), length); } - u32 fread(std::unique_ptr<u8 []> &ptr, u32 length, offs_t offset) { ptr = std::make_unique<u8 []>(length); return fread(ptr.get() + offset, length - offset); } // access to software list item information const software_info *software_entry() const noexcept; @@ -243,67 +182,62 @@ public: const std::string &working_directory() const { return m_working_directory; } // access to software list properties and ROM data areas - u8 *get_software_region(const char *tag); - u32 get_software_region_length(const char *tag); - const char *get_feature(const char *feature_name) const; - bool load_software_region(const char *tag, std::unique_ptr<u8[]> &ptr); + u8 *get_software_region(std::string_view tag); + u32 get_software_region_length(std::string_view tag); + const char *get_feature(std::string_view feature_name) const; + std::error_condition load_software_region(std::string_view tag, std::unique_ptr<u8[]> &ptr); u32 crc(); - util::hash_collection& hash() { return m_hash; } - util::hash_collection calculate_hash_on_file(util::core_file &file) const; + util::hash_collection &hash() { return m_hash; } + util::hash_collection calculate_hash_on_file(util::random_read &file) const; void battery_load(void *buffer, int length, int fill); void battery_load(void *buffer, int length, const void *def_buffer); void battery_save(const void *buffer, int length); - const char *image_type_name() const { return device_typename(image_type()); } - const std::string &instance_name() const { return m_instance_name; } const std::string &brief_instance_name() const { return m_brief_instance_name; } const std::string &canonical_instance_name() const { return m_canonical_instance_name; } - bool uses_file_extension(const char *file_extension) const; const formatlist_type &formatlist() const { return m_formatlist; } // loads an image file - image_init_result load(std::string_view path); + std::pair<std::error_condition, std::string> load(std::string_view path); // loads a softlist item by name - image_init_result load_software(std::string_view software_identifier); + std::pair<std::error_condition, std::string> load_software(std::string_view software_identifier); - image_init_result finish_load(); + std::pair<std::error_condition, std::string> finish_load(); void unload(); - image_init_result create(std::string_view path, const image_device_format *create_format, util::option_resolution *create_args); - image_init_result create(std::string_view path); - bool load_software(software_list_device &swlist, std::string_view swname, const rom_entry *entry); + std::pair<std::error_condition, std::string> create(std::string_view path, const image_device_format *create_format, util::option_resolution *create_args); + std::pair<std::error_condition, std::string> create(std::string_view path); + std::error_condition load_software(software_list_device &swlist, std::string_view swname, const rom_entry *entry); std::error_condition reopen_for_write(std::string_view path); - void set_user_loadable(bool user_loadable) { m_user_loadable = user_loadable; } + void set_user_loadable(bool user_loadable) noexcept { m_user_loadable = user_loadable; } + void set_must_be_loaded(bool must_be_loaded) noexcept { m_must_be_loaded = must_be_loaded; } bool user_loadable() const noexcept { return m_user_loadable; } + bool must_be_loaded() const noexcept { return m_must_be_loaded; } bool is_reset_and_loading() const noexcept { return m_is_reset_and_loading; } const std::string &full_software_name() const noexcept { return m_full_software_name; } protected: - // interface-level overrides + // device_interface implementation virtual void interface_config_complete() override; virtual const software_list_loader &get_software_list_loader() const; - virtual const bool use_software_list_file_extension_for_filetype() const { return false; } + virtual bool use_software_list_file_extension_for_filetype() const noexcept { return false; } - image_init_result load_internal(std::string_view path, bool is_create, int create_format, util::option_resolution *create_args); std::error_condition load_image_by_path(u32 open_flags, std::string_view path); - void clear(); - bool is_loaded() const { return m_file != nullptr; } + bool is_loaded() const noexcept { return m_file != nullptr; } - void set_image_filename(std::string_view filename); - - void clear_error(); + void set_image_tag(); void check_for_file() const { if (!m_file) throw emu_fatalerror("%s(%s): Illegal operation on unmounted image", device().shortname(), device().tag()); } void make_readonly() noexcept { m_readonly = true; } - bool image_checkhash(); + std::error_condition image_checkhash(); const software_part *find_software_item(std::string_view identifier, bool restrict_to_interface, software_list_device **device = nullptr) const; std::string software_get_default_slot(std::string_view default_card_slot) const; @@ -311,17 +245,21 @@ protected: void add_format(std::unique_ptr<image_device_format> &&format); void add_format(std::string &&name, std::string &&description, std::string &&extensions, std::string &&optspec); - // derived class overrides +private: + std::vector<u32> determine_open_plan(bool is_create); + void update_names(); + void set_image_filename(std::string_view filename); + void clear() noexcept; + std::pair<std::error_condition, std::string> load_internal(std::string_view path, bool is_create, int create_format, util::option_resolution *create_args); + std::error_condition load_software_part(std::string_view identifier); - // configuration - static const image_device_type_info *find_device_type(iodevice_t type); - static const image_device_type_info m_device_info_array[]; + bool init_phase() const; + static std::error_condition run_hash(util::random_read &file, u32 skip_bytes, util::hash_collection &hashes, const char *types); - // error related info - std::error_condition m_err; - std::string m_err_message; + // loads an image or software items and resets - called internally when we + // load an is_reset_on_load() item + void reset_and_load(std::string_view path); -private: // variables that are only non-zero when an image is mounted util::core_file::ptr m_file; std::unique_ptr<emu_file> m_mame_file; @@ -330,29 +268,27 @@ private: std::string m_basename_noext; std::string m_filetype; + // preset images regions + std::vector<std::string> m_possible_preset_regions; + std::vector<chd_file *> m_preset_images; + int m_default_region, m_current_region; + // Software information std::string m_full_software_name; const software_part *m_software_part_ptr; std::string m_software_list_name; - std::vector<u32> determine_open_plan(bool is_create); - void update_names(); - bool load_software_part(std::string_view identifier); - - bool init_phase() const; - static bool run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types); - - // loads an image or software items and resets - called internally when we - // load an is_reset_on_load() item - void reset_and_load(std::string_view path); - // creation info formatlist_type m_formatlist; // working directory; persists across mounts std::string m_working_directory; + // to notify interested parties when media changes + util::notifier<media_change_event> m_media_change_notifier; + // flags + u32 m_sequence_counter; bool m_readonly; bool m_created; @@ -370,6 +306,8 @@ private: // we want to disable command line cart loading... bool m_user_loadable; + bool m_must_be_loaded; + bool m_is_loading; bool m_is_reset_and_loading; @@ -378,4 +316,4 @@ private: // iterator typedef device_interface_enumerator<device_image_interface> image_interface_enumerator; -#endif /* MAME_EMU_DIIMAGE_H */ +#endif // MAME_EMU_DIIMAGE_H |