Merge branch 'file_create_and_format_refactorings' of https://github.com/npwoods/mame

This commit is contained in:
Vas Crabb 2016-07-07 16:03:39 +10:00
commit 630e7a2e98
9 changed files with 283 additions and 213 deletions

View File

@ -148,10 +148,10 @@ void device_image_interface::device_compute_hash(hash_collection &hashes, const
hashes.compute(reinterpret_cast<const UINT8 *>(data), length, types);
}
/*-------------------------------------------------
set_image_filename - specifies the filename of
an image
-------------------------------------------------*/
//-------------------------------------------------
// set_image_filename - specifies the filename of
// an image
//-------------------------------------------------
image_error_t device_image_interface::set_image_filename(const char *filename)
{
@ -189,28 +189,29 @@ image_error_t device_image_interface::set_image_filename(const char *filename)
CREATION FORMATS
****************************************************************************/
/*-------------------------------------------------
device_get_named_creatable_format -
accesses a specific image format available for
image creation by name
-------------------------------------------------*/
//-------------------------------------------------
// device_get_named_creatable_format -
// accesses a specific image format available for
// image creation by name
//-------------------------------------------------
const image_device_format *device_image_interface::device_get_named_creatable_format(const char *format_name)
{
for (auto &format : m_formatlist)
if (strcmp(format->name(), format_name) == 0)
if (strcmp(format->name().c_str(), format_name) == 0)
return format.get();
return nullptr;
}
/****************************************************************************
ERROR HANDLING
****************************************************************************/
/*-------------------------------------------------
image_clear_error - clear out any specified
error
-------------------------------------------------*/
//-------------------------------------------------
// image_clear_error - clear out any specified
// error
//-------------------------------------------------
void device_image_interface::clear_error()
{
@ -223,10 +224,11 @@ void device_image_interface::clear_error()
/*-------------------------------------------------
error - returns the error text for an image
error
-------------------------------------------------*/
//-------------------------------------------------
// error - returns the error text for an image
// error
//-------------------------------------------------
static const char *const messages[] =
{
"",
@ -246,9 +248,9 @@ const char *device_image_interface::error()
/*-------------------------------------------------
seterror - specifies an error on an image
-------------------------------------------------*/
//-------------------------------------------------
// seterror - specifies an error on an image
//-------------------------------------------------
void device_image_interface::seterror(image_error_t err, const char *message)
{
@ -262,10 +264,10 @@ void device_image_interface::seterror(image_error_t err, const char *message)
/*-------------------------------------------------
message - used to display a message while
loading
-------------------------------------------------*/
//-------------------------------------------------
// message - used to display a message while
// loading
//-------------------------------------------------
void device_image_interface::message(const char *format, ...)
{
@ -288,11 +290,12 @@ void device_image_interface::message(const char *format, ...)
WORKING DIRECTORIES
***************************************************************************/
/*-------------------------------------------------
try_change_working_directory - tries to change
the working directory, but only if the directory
actually exists
-------------------------------------------------*/
//-------------------------------------------------
// try_change_working_directory - tries to change
// the working directory, but only if the directory
// actually exists
//-------------------------------------------------
bool device_image_interface::try_change_working_directory(const char *subdir)
{
const osd::directory::entry *entry;
@ -314,26 +317,28 @@ bool device_image_interface::try_change_working_directory(const char *subdir)
directory.reset();
}
/* did we successfully identify the directory? */
// did we successfully identify the directory?
if (success)
m_working_directory = util::zippath_combine(m_working_directory.c_str(), subdir);
return success;
}
/*-------------------------------------------------
setup_working_directory - sets up the working
directory according to a few defaults
-------------------------------------------------*/
//-------------------------------------------------
// setup_working_directory - sets up the working
// directory according to a few defaults
//-------------------------------------------------
void device_image_interface::setup_working_directory()
{
/* first set up the working directory to be the starting directory */
// first set up the working directory to be the starting directory
osd_get_full_path(m_working_directory, ".");
/* now try browsing down to "software" */
// now try browsing down to "software"
if (try_change_working_directory("software"))
{
/* now down to a directory for this computer */
// now down to a directory for this computer
int gamedrv = driver_list::find(device().machine().system());
while(gamedrv != -1 && !try_change_working_directory(driver_list::driver(gamedrv).name))
{
@ -342,6 +347,7 @@ void device_image_interface::setup_working_directory()
}
}
//-------------------------------------------------
// working_directory - returns the working
// directory to use for this image; this is
@ -350,7 +356,7 @@ void device_image_interface::setup_working_directory()
const char * device_image_interface::working_directory()
{
/* check to see if we've never initialized the working directory */
// check to see if we've never initialized the working directory
if (m_working_directory.empty())
setup_working_directory();
@ -358,9 +364,9 @@ const char * device_image_interface::working_directory()
}
/*-------------------------------------------------
get_software_region
-------------------------------------------------*/
//-------------------------------------------------
// get_software_region
//-------------------------------------------------
UINT8 *device_image_interface::get_software_region(const char *tag)
{
@ -375,9 +381,9 @@ UINT8 *device_image_interface::get_software_region(const char *tag)
}
/*-------------------------------------------------
image_get_software_region_length
-------------------------------------------------*/
//-------------------------------------------------
// image_get_software_region_length
//-------------------------------------------------
UINT32 device_image_interface::get_software_region_length(const char *tag)
{
@ -390,9 +396,9 @@ UINT32 device_image_interface::get_software_region_length(const char *tag)
}
/*-------------------------------------------------
image_get_feature
-------------------------------------------------*/
//-------------------------------------------------
// image_get_feature
//-------------------------------------------------
const char *device_image_interface::get_feature(const char *feature_name)
{
@ -418,12 +424,13 @@ bool device_image_interface::load_software_region(const char *tag, optional_shar
return size > 0;
}
/****************************************************************************
Hash info loading
If the hash is not checked and the relevant info not loaded, force that info
to be loaded
****************************************************************************/
// ****************************************************************************
// Hash info loading
//
// If the hash is not checked and the relevant info not loaded, force that info
// to be loaded
// ****************************************************************************
void device_image_interface::run_hash(void (*partialhash)(hash_collection &, const unsigned char *, unsigned long, const char *),
hash_collection &hashes, const char *types)
@ -437,7 +444,7 @@ void device_image_interface::run_hash(void (*partialhash)(hash_collection &, con
buf.resize(size);
memset(&buf[0], 0, size);
/* read the file */
// read the file
fseek(0, SEEK_SET);
fread(&buf[0], size);
@ -446,7 +453,7 @@ void device_image_interface::run_hash(void (*partialhash)(hash_collection &, con
else
hashes.compute(&buf[0], size, types);
/* cleanup */
// cleanup
fseek(0, SEEK_SET);
}
@ -456,20 +463,20 @@ void device_image_interface::image_checkhash()
{
device_image_partialhash_func partialhash;
/* only calculate CRC if it hasn't been calculated, and the open_mode is read only */
// only calculate CRC if it hasn't been calculated, and the open_mode is read only
UINT32 crcval;
if (!m_hash.crc(crcval) && m_readonly && !m_created)
{
/* do not cause a linear read of 600 megs please */
/* TODO: use SHA1 in the CHD header as the hash */
// do not cause a linear read of 600 megs please
// TODO: use SHA1 in the CHD header as the hash
if (image_type() == IO_CDROM)
return;
/* Skip calculating the hash when we have an image mounted through a software list */
// Skip calculating the hash when we have an image mounted through a software list
if ( m_software_info_ptr )
return;
/* retrieve the partial hash func */
// retrieve the partial hash func
partialhash = get_partial_hash();
run_hash(partialhash, m_hash, hash_collection::HASH_TYPES_ALL);
@ -487,20 +494,21 @@ UINT32 device_image_interface::crc()
return crc;
}
/****************************************************************************
Battery functions
These functions provide transparent access to battery-backed RAM on an
image; typically for cartridges.
****************************************************************************/
// ****************************************************************************
// Battery functions
//
// These functions provide transparent access to battery-backed RAM on an
// image; typically for cartridges.
// ****************************************************************************
/*-------------------------------------------------
battery_load - retrieves the battery
backed RAM for an image. The file name is
created from the machine driver name and the
image name.
-------------------------------------------------*/
//-------------------------------------------------
// battery_load - retrieves the battery
// backed RAM for an image. The file name is
// created from the machine driver name and the
// image name.
//-------------------------------------------------
void device_image_interface::battery_load(void *buffer, int length, int fill)
{
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
@ -515,7 +523,7 @@ void device_image_interface::battery_load(void *buffer, int length, int fill)
if (filerr == osd_file::error::NONE)
bytes_read = file.read(buffer, length);
/* fill remaining bytes (if necessary) */
// fill remaining bytes (if necessary)
memset(((char *)buffer) + bytes_read, fill, length - bytes_read);
}
@ -527,35 +535,38 @@ void device_image_interface::battery_load(void *buffer, int length, void *def_bu
int bytes_read = 0;
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
/* try to open the battery file and read it in, if possible */
// try to open the battery file and read it in, if possible
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
filerr = file.open(fname.c_str());
if (filerr == osd_file::error::NONE)
bytes_read = file.read(buffer, length);
/* if no file was present, copy the default battery */
// if no file was present, copy the default battery
if (bytes_read == 0 && def_buffer)
memcpy((char *)buffer, (char *)def_buffer, length);
}
/*-------------------------------------------------
battery_save - stores the battery
backed RAM for an image. The file name is
created from the machine driver name and the
image name.
-------------------------------------------------*/
//-------------------------------------------------
// battery_save - stores the battery
// backed RAM for an image. The file name is
// created from the machine driver name and the
// image name.
//-------------------------------------------------
void device_image_interface::battery_save(const void *buffer, int length)
{
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
/* try to open the battery file and write it out, if possible */
// try to open the battery file and write it out, if possible
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
osd_file::error filerr = file.open(fname.c_str());
if (filerr == osd_file::error::NONE)
file.write(buffer, length);
}
//-------------------------------------------------
// uses_file_extension - update configuration
// based on completed device setup
@ -583,38 +594,40 @@ bool device_image_interface::uses_file_extension(const char *file_extension) con
return result;
}
/****************************************************************************
IMAGE LOADING
****************************************************************************/
/*-------------------------------------------------
is_loaded - quick check to determine whether an
image is loaded
-------------------------------------------------*/
// ***************************************************************************
// IMAGE LOADING
// ***************************************************************************
//-------------------------------------------------
// is_loaded - quick check to determine whether an
// image is loaded
//-------------------------------------------------
bool device_image_interface::is_loaded()
{
return (m_file != nullptr);
}
/*-------------------------------------------------
load_image_by_path - loads an image with a
specific path
-------------------------------------------------*/
//-------------------------------------------------
// load_image_by_path - loads an image with a
// specific path
//-------------------------------------------------
image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, const char *path)
{
image_error_t err;
std::string revised_path;
/* attempt to read the file */
// attempt to read the file
auto const filerr = util::zippath_fopen(path, open_flags, m_file, revised_path);
/* did the open succeed? */
// did the open succeed?
switch(filerr)
{
case osd_file::error::NONE:
/* success! */
// success!
m_readonly = (open_flags & OPEN_FLAG_WRITE) ? 0 : 1;
m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0;
err = IMAGE_ERROR_SUCCESS;
@ -622,17 +635,17 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons
case osd_file::error::NOT_FOUND:
case osd_file::error::ACCESS_DENIED:
/* file not found (or otherwise cannot open); continue */
// file not found (or otherwise cannot open); continue
err = IMAGE_ERROR_FILENOTFOUND;
break;
case osd_file::error::OUT_OF_MEMORY:
/* out of memory */
// out of memory
err = IMAGE_ERROR_OUTOFMEMORY;
break;
case osd_file::error::ALREADY_OPEN:
/* this shouldn't happen */
// this shouldn't happen
err = IMAGE_ERROR_ALREADYOPEN;
break;
@ -640,12 +653,12 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons
case osd_file::error::TOO_MANY_FILES:
case osd_file::error::INVALID_DATA:
default:
/* other errors */
// other errors
err = IMAGE_ERROR_INTERNAL;
break;
}
/* if successful, set the file name */
// if successful, set the file name
if (filerr == osd_file::error::NONE)
set_image_filename(revised_path.c_str());
@ -659,14 +672,14 @@ int device_image_interface::reopen_for_write(const char *path)
image_error_t err;
std::string revised_path;
/* attempt to open the file for writing*/
// attempt to open the file for writing
auto const filerr = util::zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path);
/* did the open succeed? */
// did the open succeed?
switch(filerr)
{
case osd_file::error::NONE:
/* success! */
// success!
m_readonly = 0;
m_created = 1;
err = IMAGE_ERROR_SUCCESS;
@ -674,17 +687,17 @@ int device_image_interface::reopen_for_write(const char *path)
case osd_file::error::NOT_FOUND:
case osd_file::error::ACCESS_DENIED:
/* file not found (or otherwise cannot open); continue */
// file not found (or otherwise cannot open); continue
err = IMAGE_ERROR_FILENOTFOUND;
break;
case osd_file::error::OUT_OF_MEMORY:
/* out of memory */
// out of memory
err = IMAGE_ERROR_OUTOFMEMORY;
break;
case osd_file::error::ALREADY_OPEN:
/* this shouldn't happen */
// this shouldn't happen
err = IMAGE_ERROR_ALREADYOPEN;
break;
@ -692,28 +705,29 @@ int device_image_interface::reopen_for_write(const char *path)
case osd_file::error::TOO_MANY_FILES:
case osd_file::error::INVALID_DATA:
default:
/* other errors */
// other errors
err = IMAGE_ERROR_INTERNAL;
break;
}
/* if successful, set the file name */
// if successful, set the file name
if (filerr == osd_file::error::NONE)
set_image_filename(revised_path.c_str());
return err;
}
/*-------------------------------------------------
determine_open_plan - determines which open
flags to use, and in what order
-------------------------------------------------*/
//-------------------------------------------------
// determine_open_plan - determines which open
// flags to use, and in what order
//-------------------------------------------------
void device_image_interface::determine_open_plan(int is_create, UINT32 *open_plan)
{
int i = 0;
/* emit flags */
// emit flags
if (!is_create && is_readable() && is_writeable())
open_plan[i++] = OPEN_FLAG_READ | OPEN_FLAG_WRITE;
if (!is_create && !is_readable() && is_writeable())
@ -725,11 +739,12 @@ void device_image_interface::determine_open_plan(int is_create, UINT32 *open_pla
open_plan[i] = 0;
}
/*-------------------------------------------------
dump_wrong_and_correct_checksums - dump an
error message containing the wrong and the
correct checksums for a given software item
-------------------------------------------------*/
//-------------------------------------------------
// dump_wrong_and_correct_checksums - dump an
// error message containing the wrong and the
// correct checksums for a given software item
//-------------------------------------------------
static void dump_wrong_and_correct_checksums(const hash_collection &hashes, const hash_collection &acthashes)
{
@ -737,17 +752,18 @@ static void dump_wrong_and_correct_checksums(const hash_collection &hashes, cons
osd_printf_error(" FOUND: %s\n", acthashes.macro_string().c_str());
}
/*-------------------------------------------------
verify_length_and_hash - verify the length
and hash signatures of a file
-------------------------------------------------*/
//-------------------------------------------------
// verify_length_and_hash - verify the length
// and hash signatures of a file
//-------------------------------------------------
static int verify_length_and_hash(emu_file *file, const char *name, UINT32 explength, const hash_collection &hashes)
{
int retVal = 0;
if (file==nullptr) return 0;
/* verify length */
// verify length
UINT32 actlength = file->size();
if (explength != actlength)
{
@ -755,21 +771,21 @@ static int verify_length_and_hash(emu_file *file, const char *name, UINT32 exple
retVal++;
}
/* If there is no good dump known, write it */
// If there is no good dump known, write it
hash_collection &acthashes = file->hashes(hashes.hash_types().c_str());
if (hashes.flag(hash_collection::FLAG_NO_DUMP))
{
osd_printf_error("%s NO GOOD DUMP KNOWN\n", name);
}
/* verify checksums */
// verify checksums
else if (hashes != acthashes)
{
/* otherwise, it's just bad */
// otherwise, it's just bad
osd_printf_error("%s WRONG CHECKSUMS:\n", name);
dump_wrong_and_correct_checksums(hashes, acthashes);
retVal++;
}
/* If it matches, but it is actually a bad dump, write it */
// If it matches, but it is actually a bad dump, write it
else if (hashes.flag(hash_collection::FLAG_BAD_DUMP))
{
osd_printf_error("%s NEEDS REDUMP\n",name);
@ -777,9 +793,10 @@ static int verify_length_and_hash(emu_file *file, const char *name, UINT32 exple
return retVal;
}
/*-------------------------------------------------
load_software - software image loading
-------------------------------------------------*/
//-------------------------------------------------
// load_software - software image loading
//-------------------------------------------------
bool device_image_interface::load_software(software_list_device &swlist, const char *swname, const rom_entry *start)
{
@ -789,11 +806,11 @@ bool device_image_interface::load_software(software_list_device &swlist, const c
int warningcount = 0;
for (region = start; region != nullptr; region = rom_next_region(region))
{
/* loop until we hit the end of this region */
// loop until we hit the end of this region
const rom_entry *romp = region + 1;
while (!ROMENTRY_ISREGIONEND(romp))
{
/* handle files */
// handle files
if (ROMENTRY_ISFILE(romp))
{
osd_file::error filerr = osd_file::error::NOT_FOUND;
@ -882,9 +899,10 @@ bool device_image_interface::load_software(software_list_device &swlist, const c
return retVal;
}
/*-------------------------------------------------
load_internal - core image loading
-------------------------------------------------*/
//-------------------------------------------------
// load_internal - core image loading
//-------------------------------------------------
bool device_image_interface::load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args, bool just_load)
{
@ -897,16 +915,16 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
std::string pathstr(path);
bool filename_has_period = (pathstr.find_last_of('.') != -1) ? TRUE : FALSE;
/* first unload the image */
// first unload the image
unload();
/* clear any possible error messages */
// clear any possible error messages
clear_error();
/* we are now loading */
// we are now loading
m_is_loading = TRUE;
/* record the filename */
// record the filename
m_err = set_image_filename(path);
if (m_err)
@ -914,7 +932,7 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
if (core_opens_image_file())
{
/* Check if there's a software list defined for this device and use that if we're not creating an image */
// Check if there's a software list defined for this device and use that if we're not creating an image
if (!filename_has_period && !just_load)
{
softload = load_software_part(path, m_software_part_ptr);
@ -941,20 +959,20 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
if (is_create || filename_has_period)
{
/* determine open plan */
// determine open plan
determine_open_plan(is_create, open_plan);
/* attempt to open the file in various ways */
// attempt to open the file in various ways
for (i = 0; !m_file && open_plan[i]; i++)
{
/* open the file */
// open the file
m_err = load_image_by_path(open_plan[i], path);
if (m_err && (m_err != IMAGE_ERROR_FILENOTFOUND))
goto done;
}
}
/* Copy some image information when we have been loaded through a software list */
// Copy some image information when we have been loaded through a software list
if ( m_software_info_ptr )
{
// sanitize
@ -968,7 +986,7 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
//m_playable = m_software_info_ptr->supported();
}
/* did we fail to find the file? */
// did we fail to find the file?
if (!is_loaded() && !softload)
{
m_err = IMAGE_ERROR_FILENOTFOUND;
@ -976,7 +994,7 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
}
}
/* call device load or create */
// call device load or create
m_create_format = create_format;
m_create_args = create_args;
@ -985,7 +1003,7 @@ bool device_image_interface::load_internal(const char *path, bool is_create, int
if (m_err)
goto done;
}
/* success! */
// success!
done:
if (just_load) {
@ -1022,18 +1040,19 @@ done:
/*-------------------------------------------------
load - load an image into MESS
-------------------------------------------------*/
//-------------------------------------------------
// load - load an image into MAME
//-------------------------------------------------
bool device_image_interface::load(const char *path)
{
return load_internal(path, FALSE, 0, nullptr, FALSE);
}
/*-------------------------------------------------
open_image_file - opening plain image file
-------------------------------------------------*/
//-------------------------------------------------
// open_image_file - opening plain image file
//-------------------------------------------------
bool device_image_interface::open_image_file(emu_options &options)
{
@ -1049,10 +1068,11 @@ bool device_image_interface::open_image_file(emu_options &options)
return false;
}
/*-------------------------------------------------
image_finish_load - special call - only use
from core
-------------------------------------------------*/
//-------------------------------------------------
// image_finish_load - special call - only use
// from core
//-------------------------------------------------
bool device_image_interface::finish_load()
{
@ -1073,7 +1093,7 @@ bool device_image_interface::finish_load()
}
else
{
/* using device load */
// using device load
err = call_load();
if (err)
{
@ -1089,9 +1109,10 @@ bool device_image_interface::finish_load()
return err;
}
/*-------------------------------------------------
create - create a image
-------------------------------------------------*/
//-------------------------------------------------
// create - create a image
//-------------------------------------------------
bool device_image_interface::create(const char *path, const image_device_format *create_format, option_resolution *create_args)
{
@ -1109,10 +1130,10 @@ bool device_image_interface::create(const char *path, const image_device_format
}
/*-------------------------------------------------
clear - clear all internal data pertaining
to an image
-------------------------------------------------*/
//-------------------------------------------------
// clear - clear all internal data pertaining
// to an image
//-------------------------------------------------
void device_image_interface::clear()
{
@ -1136,9 +1157,10 @@ void device_image_interface::clear()
m_software_list_name.clear();
}
/*-------------------------------------------------
unload - main call to unload an image
-------------------------------------------------*/
//-------------------------------------------------
// unload - main call to unload an image
//-------------------------------------------------
void device_image_interface::unload()
{
@ -1150,9 +1172,10 @@ void device_image_interface::unload()
clear_error();
}
/*-------------------------------------------------
update_names - update brief and instance names
-------------------------------------------------*/
//-------------------------------------------------
// update_names - update brief and instance names
//-------------------------------------------------
void device_image_interface::update_names(const device_type device_type, const char *inst, const char *brief)
{
@ -1357,7 +1380,7 @@ std::string device_image_interface::software_get_default_slot(const char *defaul
return result;
}
/* ----------------------------------------------------------------------- */
//----------------------------------------------------------------------------
static int image_fseek_thunk(void *file, INT64 offset, int whence)
{
@ -1383,7 +1406,7 @@ static UINT64 image_fsize_thunk(void *file)
return image->length();
}
/* ----------------------------------------------------------------------- */
//----------------------------------------------------------------------------
struct io_procs image_ioprocs =
{

View File

@ -78,10 +78,10 @@ public:
m_extensions(extensions),
m_optspec(optspec) { }
const char *name() const { return m_name.c_str(); }
const char *description() const { return m_description.c_str(); }
const char *extensions() const { return m_extensions.c_str(); }
const char *optspec() const { return m_optspec.c_str(); }
const std::string &name() const { return m_name; }
const std::string &description() const { return m_description; }
const std::string &extensions() const { return m_extensions; }
const std::string &optspec() const { return m_optspec; }
private:
std::string m_name;
@ -133,6 +133,8 @@ typedef void (*device_image_partialhash_func)(hash_collection &, const unsigned
class device_image_interface : public device_interface
{
public:
typedef std::vector<std::unique_ptr<image_device_format>> formatlist_type;
// construction/destruction
device_image_interface(const machine_config &mconfig, device_t &device);
virtual ~device_image_interface();
@ -221,7 +223,7 @@ public:
const char *instance_name() const { return m_instance_name.c_str(); }
const char *brief_instance_name() const { return m_brief_instance_name.c_str(); }
bool uses_file_extension(const char *file_extension) const;
const std::vector<std::unique_ptr<image_device_format>> &formatlist() const { return m_formatlist; }
const formatlist_type &formatlist() const { return m_formatlist; }
bool load(const char *path);
bool open_image_file(emu_options &options);
@ -315,7 +317,7 @@ protected:
std::string m_instance_name;
/* creation info */
std::vector<std::unique_ptr<image_device_format>> m_formatlist;
formatlist_type m_formatlist;
/* in the case of arcade cabinet with fixed carts inserted,
we want to disable command line cart loading... */

View File

@ -135,42 +135,19 @@ void menu_confirm_save_as::handle()
FILE CREATE MENU
***************************************************************************/
//-------------------------------------------------
// is_valid_filename_char - tests to see if a
// character is valid in a filename
//-------------------------------------------------
static int is_valid_filename_char(unicode_char unichar)
{
// this should really be in the OSD layer, and it shouldn't be 7-bit bullshit
static const char valid_filename_char[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00-0f
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10-1f
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, // !"#$%&'()*+,-./
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 0123456789:;<=>?
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // @ABCDEFGHIJKLMNO
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // PQRSTUVWXYZ[\]^_
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // `abcdefghijklmno
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, // pqrstuvwxyz{|}~
};
return (unichar < ARRAY_LENGTH(valid_filename_char)) && valid_filename_char[unichar];
}
//-------------------------------------------------
// ctor
//-------------------------------------------------
menu_file_create::menu_file_create(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string &current_directory, std::string &current_file, bool *ok)
menu_file_create::menu_file_create(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string &current_directory, std::string &current_file, bool &ok)
: menu(mui, container)
, m_current_directory(current_directory)
, m_current_file(current_file)
, m_current_format(nullptr)
, m_ok(ok)
{
m_image = image;
m_ok = ok;
*m_ok = true;
m_ok = true;
auto const sep = current_file.rfind(PATH_SEPARATOR);
m_filename.reserve(1024);
@ -271,12 +248,12 @@ void menu_file_create::handle()
case IPT_SPECIAL:
if (get_selection() == ITEMREF_NEW_IMAGE_NAME)
{
input_character(m_filename, event->unichar, &is_valid_filename_char);
input_character(m_filename, event->unichar, &osd_is_valid_filename_char);
reset(reset_options::REMEMBER_POSITION);
}
break;
case IPT_UI_CANCEL:
*m_ok = false;
m_ok = false;
break;
}
}

View File

@ -38,7 +38,7 @@ private:
class menu_file_create : public menu
{
public:
menu_file_create(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string &current_directory, std::string &current_file, bool *ok);
menu_file_create(mame_ui_manager &mui, render_container *container, device_image_interface *image, std::string &current_directory, std::string &current_file, bool &ok);
virtual ~menu_file_create() override;
virtual void populate() override;
virtual void handle() override;
@ -52,7 +52,7 @@ private:
std::string m_filename;
protected:
bool * m_ok;
bool & m_ok;
};
// ======================> menu_select_format

View File

@ -157,7 +157,7 @@ void menu_control_floppy_image::handle()
break;
case menu_select_rw::result::WRITE_OTHER:
menu::stack_push<menu_file_create>(ui(), container, image, m_current_directory, m_current_file, &create_ok);
menu::stack_push<menu_file_create>(ui(), container, image, m_current_directory, m_current_file, create_ok);
state = CHECK_CREATE;
break;

View File

@ -278,7 +278,7 @@ void menu_control_device_image::handle()
break;
case menu_file_selector::result::CREATE:
menu::stack_push<menu_file_create>(ui(), container, image, m_current_directory, m_current_file, &create_ok);
menu::stack_push<menu_file_create>(ui(), container, image, m_current_directory, m_current_file, create_ok);
state = CHECK_CREATE;
break;

View File

@ -14,6 +14,7 @@
#include "strconv.h"
#include "winutil.h"
#include "winutf8.h"
#include "unicode.h"
// MAME headers
#include "osdcore.h"
@ -465,6 +466,39 @@ const char *osd_get_volume_name(int idx)
//============================================================
// osd_is_valid_filename_char
//============================================================
bool osd_is_valid_filename_char(unicode_char uchar)
{
return osd_is_valid_filepath_char(uchar)
&& uchar != '/'
&& uchar != '\\'
&& uchar != ':';
}
//============================================================
// osd_is_valid_filepath_char
//============================================================
bool osd_is_valid_filepath_char(unicode_char uchar)
{
return uchar >= 0x20
&& uchar != '<'
&& uchar != '>'
&& uchar != '\"'
&& uchar != '|'
&& uchar != '?'
&& uchar != '*'
&& !(uchar >= '\x7F' && uchar <= '\x9F')
&& uchar_isvalid(uchar);
}
//============================================================
// win_error_to_file_error
//============================================================

View File

@ -85,6 +85,11 @@ using INT64 = std::int64_t;
/* pointer-sized values */
using FPTR = uintptr_t;
/* unicode types */
using utf16_char = std::uint16_t;
using unicode_char = std::uint32_t;
/***************************************************************************

View File

@ -290,9 +290,38 @@ int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UIN
The number of characters required to form a Unicode character.
-----------------------------------------------------------------------------*/
int osd_uchar_from_osdchar(UINT32 /* unicode_char */ *uchar, const char *osdchar, size_t count);
int osd_uchar_from_osdchar(unicode_char *uchar, const char *osdchar, size_t count);
/*-----------------------------------------------------------------------------
osd_is_valid_filename_char: is the given character legal for filenames?
Parameters:
uchar - the character to check
Return value:
Whether this character is legal in a filename
-----------------------------------------------------------------------------*/
bool osd_is_valid_filename_char(unicode_char uchar);
/*-----------------------------------------------------------------------------
osd_is_valid_filepath_char: is the given character legal for paths?
Parameters:
uchar - the character to check
Return value:
Whether this character is legal in a file path
-----------------------------------------------------------------------------*/
bool osd_is_valid_filepath_char(unicode_char uchar);
/***************************************************************************
DIRECTORY INTERFACES