mirror of
https://github.com/libretro/same_cdi.git
synced 2026-11-07 12:37:58 -10:00
Update diimage.
This commit is contained in:
1 parent
27bfc22efd
commit
cf04e0fd88
2 files changed
+441
-502
No files matched your search
+358
-357
File diff suppressed because it is too large.
Load diff
+83
-145
@@ -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
|
||||
|
||||
// configuration
|
||||
static const image_device_type_info *find_device_type(iodevice_t type);
|
||||
static const image_device_type_info m_device_info_array[];
|
||||
|
||||
// error related info
|
||||
std::error_condition m_err;
|
||||
std::string m_err_message;
|
||||
|
||||
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);
|
||||
|
||||
bool init_phase() const;
|
||||
static std::error_condition run_hash(util::random_read &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);
|
||||
|
||||
// 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
|
||||
Reference in new issue
Block a user