mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Cleanup of image device base classes and prepare for rewrite (no whatsnew)
This commit is contained in:
parent
6312851a55
commit
2749c957bc
@ -39,9 +39,7 @@
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "emuopts.h"
|
||||
#include "devlegcy.h"
|
||||
#include "zippath.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -54,20 +52,6 @@
|
||||
|
||||
legacy_image_device_base::~legacy_image_device_base()
|
||||
{
|
||||
image_device_format **formatptr = &m_formatlist;
|
||||
|
||||
/* free all entries */
|
||||
while (*formatptr != NULL)
|
||||
{
|
||||
image_device_format *entry = *formatptr;
|
||||
*formatptr = entry->m_next;
|
||||
global_free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
device_image_partialhash_func legacy_image_device_base::get_partial_hash() const
|
||||
{
|
||||
return reinterpret_cast<device_image_partialhash_func>(get_legacy_fct(DEVINFO_FCT_IMAGE_PARTIAL_HASH));
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
@ -80,10 +64,7 @@ device_image_partialhash_func legacy_image_device_base::get_partial_hash() const
|
||||
|
||||
legacy_image_device_base::legacy_image_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, device_get_config_func get_config)
|
||||
: legacy_device_base(mconfig, type, tag, owner, clock, get_config),
|
||||
device_image_interface(mconfig, *this),
|
||||
m_create_option_guide(NULL),
|
||||
m_formatlist(NULL),
|
||||
m_is_loading(FALSE)
|
||||
device_image_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -103,20 +84,6 @@ void legacy_image_device_base::device_config_complete()
|
||||
formatptr = &m_formatlist;
|
||||
int cnt = 0;
|
||||
|
||||
m_type = static_cast<iodevice_t>(get_legacy_int(DEVINFO_INT_IMAGE_TYPE));
|
||||
m_readable = get_legacy_int(DEVINFO_INT_IMAGE_READABLE)!=0;
|
||||
m_writeable = get_legacy_int(DEVINFO_INT_IMAGE_WRITEABLE)!=0;
|
||||
m_creatable = get_legacy_int(DEVINFO_INT_IMAGE_CREATABLE)!=0;
|
||||
m_must_be_loaded = get_legacy_int(DEVINFO_INT_IMAGE_MUST_BE_LOADED)!=0;
|
||||
m_reset_on_load = get_legacy_int(DEVINFO_INT_IMAGE_RESET_ON_LOAD)!=0;
|
||||
m_has_partial_hash = get_legacy_int(DEVINFO_FCT_IMAGE_PARTIAL_HASH)!=0;
|
||||
|
||||
m_interface_name = get_legacy_string(DEVINFO_STR_IMAGE_INTERFACE);
|
||||
|
||||
m_file_extensions = get_legacy_string(DEVINFO_STR_IMAGE_FILE_EXTENSIONS);
|
||||
|
||||
m_create_option_guide = reinterpret_cast<const option_guide *>(get_legacy_ptr(DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE));
|
||||
|
||||
int format_count = get_legacy_int(DEVINFO_INT_IMAGE_CREATE_OPTCOUNT);
|
||||
|
||||
for (int i = 0; i < format_count; i++)
|
||||
@ -144,482 +111,29 @@ void legacy_image_device_base::device_config_complete()
|
||||
{
|
||||
if (this == image)
|
||||
index = count;
|
||||
if (image->image_type_direct() == m_type)
|
||||
if (image->image_type() == image_type())
|
||||
count++;
|
||||
}
|
||||
if (count > 1) {
|
||||
m_instance_name.printf("%s%d", device_typename(m_type), index + 1);
|
||||
m_brief_instance_name.printf("%s%d", device_brieftypename(m_type), index + 1);
|
||||
m_instance_name.printf("%s%d", device_typename(image_type()), index + 1);
|
||||
m_brief_instance_name.printf("%s%d", device_brieftypename(image_type()), index + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instance_name = device_typename(m_type);
|
||||
m_brief_instance_name = device_brieftypename(m_type);
|
||||
m_instance_name = device_typename(image_type());
|
||||
m_brief_instance_name = device_brieftypename(image_type());
|
||||
}
|
||||
// Override in case of hardcoded values
|
||||
if (strlen(get_legacy_string(DEVINFO_STR_IMAGE_INSTANCE_NAME))>0) {
|
||||
m_instance_name = get_legacy_string(DEVINFO_STR_IMAGE_INSTANCE_NAME);
|
||||
m_instance_name = get_legacy_string(DEVINFO_STR_IMAGE_INSTANCE_NAME);
|
||||
}
|
||||
if (strlen(get_legacy_string(DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME))>0) {
|
||||
m_brief_instance_name = get_legacy_string(DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// uses_file_extension - update configuration
|
||||
// based on completed device setup
|
||||
//-------------------------------------------------
|
||||
|
||||
bool legacy_image_device_base::uses_file_extension(const char *file_extension) const
|
||||
{
|
||||
bool result = FALSE;
|
||||
|
||||
if (file_extension[0] == '.')
|
||||
file_extension++;
|
||||
|
||||
/* find the extensions */
|
||||
astring extensions(m_file_extensions);
|
||||
char *ext = strtok((char*)extensions.cstr(),",");
|
||||
while (ext != NULL)
|
||||
{
|
||||
if (!mame_stricmp(ext, file_extension))
|
||||
{
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
ext = strtok (NULL, ",");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
IMAGE LOADING
|
||||
****************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
is_loaded - quick check to determine whether an
|
||||
image is loaded
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool legacy_image_device_base::is_loaded()
|
||||
{
|
||||
return (m_file != NULL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
load_image_by_path - loads an image with a
|
||||
specific path
|
||||
-------------------------------------------------*/
|
||||
|
||||
image_error_t legacy_image_device_base::load_image_by_path(UINT32 open_flags, const char *path)
|
||||
{
|
||||
file_error filerr = FILERR_NOT_FOUND;
|
||||
image_error_t err = IMAGE_ERROR_FILENOTFOUND;
|
||||
astring revised_path;
|
||||
|
||||
/* attempt to read the file */
|
||||
filerr = zippath_fopen(path, open_flags, &m_file, &revised_path);
|
||||
|
||||
/* did the open succeed? */
|
||||
switch(filerr)
|
||||
{
|
||||
case FILERR_NONE:
|
||||
/* success! */
|
||||
m_readonly = (open_flags & OPEN_FLAG_WRITE) ? 0 : 1;
|
||||
m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0;
|
||||
err = IMAGE_ERROR_SUCCESS;
|
||||
break;
|
||||
|
||||
case FILERR_NOT_FOUND:
|
||||
case FILERR_ACCESS_DENIED:
|
||||
/* file not found (or otherwise cannot open); continue */
|
||||
err = IMAGE_ERROR_FILENOTFOUND;
|
||||
break;
|
||||
|
||||
case FILERR_OUT_OF_MEMORY:
|
||||
/* out of memory */
|
||||
err = IMAGE_ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
|
||||
case FILERR_ALREADY_OPEN:
|
||||
/* this shouldn't happen */
|
||||
err = IMAGE_ERROR_ALREADYOPEN;
|
||||
break;
|
||||
|
||||
case FILERR_FAILURE:
|
||||
case FILERR_TOO_MANY_FILES:
|
||||
case FILERR_INVALID_DATA:
|
||||
default:
|
||||
/* other errors */
|
||||
err = IMAGE_ERROR_INTERNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if successful, set the file name */
|
||||
if (filerr == FILERR_NONE)
|
||||
set_image_filename(revised_path);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
determine_open_plan - determines which open
|
||||
flags to use, and in what order
|
||||
-------------------------------------------------*/
|
||||
|
||||
void legacy_image_device_base::determine_open_plan(int is_create, UINT32 *open_plan)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* 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())
|
||||
open_plan[i++] = OPEN_FLAG_WRITE;
|
||||
if (!is_create && is_readable())
|
||||
open_plan[i++] = OPEN_FLAG_READ;
|
||||
if (is_writeable() && is_creatable())
|
||||
open_plan[i++] = OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE;
|
||||
open_plan[i] = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
load_software - software image loading
|
||||
-------------------------------------------------*/
|
||||
bool legacy_image_device_base::load_software(char *swlist, char *swname, rom_entry *start)
|
||||
{
|
||||
astring locationtag, breakstr("%");
|
||||
const rom_entry *region;
|
||||
astring regiontag;
|
||||
bool retVal = FALSE;
|
||||
for (region = start; region != NULL; region = rom_next_region(region))
|
||||
{
|
||||
/* loop until we hit the end of this region */
|
||||
const rom_entry *romp = region + 1;
|
||||
while (!ROMENTRY_ISREGIONEND(romp))
|
||||
{
|
||||
/* handle files */
|
||||
if (ROMENTRY_ISFILE(romp))
|
||||
{
|
||||
file_error filerr = FILERR_NOT_FOUND;
|
||||
|
||||
UINT32 crc = 0;
|
||||
bool has_crc = hash_collection(ROM_GETHASHDATA(romp)).crc(crc);
|
||||
|
||||
// attempt reading up the chain through the parents and create a locationtag astring in the format
|
||||
// " swlist % clonename % parentname "
|
||||
// below, we have the code to split the elements and to create paths to load from
|
||||
|
||||
software_list *software_list_ptr = software_list_open(machine().options(), swlist, FALSE, NULL);
|
||||
if (software_list_ptr)
|
||||
{
|
||||
for (software_info *swinfo = software_list_find(software_list_ptr, swname, NULL); swinfo != NULL; )
|
||||
{
|
||||
if (swinfo != NULL)
|
||||
{
|
||||
astring tmp(swinfo->shortname);
|
||||
locationtag.cat(tmp);
|
||||
locationtag.cat(breakstr);
|
||||
//printf("%s\n", locationtag.cstr());
|
||||
}
|
||||
const char *parentname = software_get_clone(machine().options(), swlist, swinfo->shortname);
|
||||
if (parentname != NULL)
|
||||
swinfo = software_list_find(software_list_ptr, parentname, NULL);
|
||||
else
|
||||
swinfo = NULL;
|
||||
}
|
||||
// strip the final '%'
|
||||
locationtag.del(locationtag.len() - 1, 1);
|
||||
software_list_close(software_list_ptr);
|
||||
}
|
||||
|
||||
if (software_get_support(machine().options(), swlist, swname) == SOFTWARE_SUPPORTED_PARTIAL)
|
||||
mame_printf_error("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist);
|
||||
|
||||
if (software_get_support(machine().options(), swlist, swname) == SOFTWARE_SUPPORTED_NO)
|
||||
mame_printf_error("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist);
|
||||
|
||||
// check if locationtag actually contains two locations separated by '%'
|
||||
// (i.e. check if we are dealing with a clone in softwarelist)
|
||||
astring tag2, tag3, tag4(locationtag), tag5;
|
||||
int separator = tag4.chr(0, '%');
|
||||
if (separator != -1)
|
||||
{
|
||||
// we are loading a clone through softlists, split the setname from the parentname
|
||||
tag5.cpysubstr(tag4, separator + 1, tag4.len() - separator + 1);
|
||||
tag4.del(separator, tag4.len() - separator);
|
||||
}
|
||||
|
||||
// prepare locations where we have to load from: list/parentname & list/clonename
|
||||
astring tag1(swlist);
|
||||
tag1.cat(PATH_SEPARATOR);
|
||||
tag2.cpy(tag1.cat(tag4));
|
||||
tag1.cpy(swlist);
|
||||
tag1.cat(PATH_SEPARATOR);
|
||||
tag3.cpy(tag1.cat(tag5));
|
||||
|
||||
if (tag5.chr(0, '%') != -1)
|
||||
fatalerror("We do not support clones of clones!\n");
|
||||
|
||||
// try to load from the available location(s):
|
||||
// - if we are not using lists, we have regiontag only;
|
||||
// - if we are using lists, we have: list/clonename, list/parentname, clonename, parentname
|
||||
// try to load from list/setname
|
||||
if ((m_mame_file == NULL) && (tag2.cstr() != NULL))
|
||||
filerr = common_process_file(machine().options(), tag2.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
// try to load from list/parentname
|
||||
if ((m_mame_file == NULL) && (tag3.cstr() != NULL))
|
||||
filerr = common_process_file(machine().options(), tag3.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
// try to load from setname
|
||||
if ((m_mame_file == NULL) && (tag4.cstr() != NULL))
|
||||
filerr = common_process_file(machine().options(), tag4.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
// try to load from parentname
|
||||
if ((m_mame_file == NULL) && (tag5.cstr() != NULL))
|
||||
filerr = common_process_file(machine().options(), tag5.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
|
||||
if (filerr == FILERR_NONE)
|
||||
{
|
||||
m_file = *m_mame_file;
|
||||
retVal = TRUE;
|
||||
}
|
||||
|
||||
break; // load first item for start
|
||||
}
|
||||
romp++; /* something else; skip */
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
load_internal - core image loading
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool legacy_image_device_base::load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args)
|
||||
{
|
||||
UINT32 open_plan[4];
|
||||
int i;
|
||||
bool softload = FALSE;
|
||||
m_from_swlist = FALSE;
|
||||
|
||||
// if the path contains no period, we are using softlists, so we won't create an image
|
||||
astring pathstr(path);
|
||||
bool filename_has_period = (pathstr.rchr(0, '.') != -1) ? TRUE : FALSE;
|
||||
|
||||
/* first unload the image */
|
||||
unload();
|
||||
|
||||
/* clear any possible error messages */
|
||||
clear_error();
|
||||
|
||||
/* we are now loading */
|
||||
m_is_loading = TRUE;
|
||||
|
||||
/* record the filename */
|
||||
m_err = set_image_filename(path);
|
||||
|
||||
if (m_err)
|
||||
goto done;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
softload = load_software_part( this, path, &m_software_info_ptr, &m_software_part_ptr, &m_full_software_name );
|
||||
// if we had launched from softlist with a specified part, e.g. "shortname:part"
|
||||
// we would have recorded the wrong name, so record it again based on software_info
|
||||
if (m_software_info_ptr && m_software_info_ptr->shortname)
|
||||
m_err = set_image_filename(m_software_info_ptr->shortname);
|
||||
|
||||
m_from_swlist = TRUE;
|
||||
}
|
||||
|
||||
if (is_create || filename_has_period)
|
||||
{
|
||||
/* determine open plan */
|
||||
determine_open_plan(is_create, open_plan);
|
||||
|
||||
/* attempt to open the file in various ways */
|
||||
for (i = 0; !m_file && open_plan[i]; i++)
|
||||
{
|
||||
/* 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 */
|
||||
if ( m_software_info_ptr )
|
||||
{
|
||||
m_longname = m_software_info_ptr->longname;
|
||||
m_manufacturer = m_software_info_ptr->publisher;
|
||||
m_year = m_software_info_ptr->year;
|
||||
//m_playable = m_software_info_ptr->supported;
|
||||
}
|
||||
|
||||
/* did we fail to find the file? */
|
||||
if (!is_loaded() && !softload)
|
||||
{
|
||||
m_err = IMAGE_ERROR_FILENOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* call device load or create */
|
||||
m_create_format = create_format;
|
||||
m_create_args = create_args;
|
||||
|
||||
if (m_init_phase==FALSE) {
|
||||
m_err = (image_error_t)finish_load();
|
||||
if (m_err)
|
||||
goto done;
|
||||
}
|
||||
/* success! */
|
||||
|
||||
done:
|
||||
if (m_err!=0) {
|
||||
if (!m_init_phase)
|
||||
{
|
||||
if (machine().phase() == MACHINE_PHASE_RUNNING)
|
||||
popmessage("Error: Unable to %s image '%s': %s\n", is_create ? "create" : "load", path, error());
|
||||
else
|
||||
mame_printf_error("Error: Unable to %s image '%s': %s", is_create ? "create" : "load", path, error());
|
||||
}
|
||||
clear();
|
||||
}
|
||||
else {
|
||||
/* do we need to reset the CPU? only schedule it if load/create is successful */
|
||||
if (device().machine().time() > attotime::zero && is_reset_on_load())
|
||||
device().machine().schedule_hard_reset();
|
||||
else
|
||||
{
|
||||
if (!m_init_phase)
|
||||
{
|
||||
if (machine().phase() == MACHINE_PHASE_RUNNING)
|
||||
popmessage("Image '%s' was successfully %s.", path, is_create ? "created" : "loaded");
|
||||
else
|
||||
mame_printf_info("Image '%s' was successfully %s.\n", path, is_create ? "created" : "loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_err ? IMAGE_INIT_FAIL : IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
load - load an image into MESS
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool legacy_image_device_base::load(const char *path)
|
||||
{
|
||||
return load_internal(path, FALSE, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
image_finish_load - special call - only use
|
||||
from core
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool legacy_image_device_base::finish_load()
|
||||
{
|
||||
bool err = IMAGE_INIT_PASS;
|
||||
|
||||
if (m_is_loading)
|
||||
{
|
||||
image_checkhash();
|
||||
|
||||
if (m_from_swlist)
|
||||
call_display_info();
|
||||
|
||||
if (has_been_created() && get_legacy_fct(DEVINFO_FCT_IMAGE_CREATE) != NULL)
|
||||
{
|
||||
err = call_create(m_create_format, m_create_args);
|
||||
if (err)
|
||||
{
|
||||
if (!m_err)
|
||||
m_err = IMAGE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* using device load */
|
||||
err = call_load();
|
||||
if (err)
|
||||
{
|
||||
if (!m_err)
|
||||
m_err = IMAGE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_is_loading = FALSE;
|
||||
m_create_format = 0;
|
||||
m_create_args = NULL;
|
||||
m_init_phase = FALSE;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
create - create a image
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool legacy_image_device_base::create(const char *path, const image_device_format *create_format, option_resolution *create_args)
|
||||
{
|
||||
int format_index = (create_format != NULL) ? create_format->m_index : 0;
|
||||
return load_internal(path, TRUE, format_index, create_args);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
clear - clear all internal data pertaining
|
||||
to an image
|
||||
-------------------------------------------------*/
|
||||
|
||||
void legacy_image_device_base::clear()
|
||||
{
|
||||
if (m_mame_file)
|
||||
{
|
||||
global_free(m_mame_file);
|
||||
m_mame_file = NULL;
|
||||
m_file = NULL;
|
||||
} else {
|
||||
if (m_file)
|
||||
{
|
||||
core_fclose(m_file);
|
||||
m_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_image_name.reset();
|
||||
m_readonly = false;
|
||||
m_created = false;
|
||||
|
||||
m_longname.reset();
|
||||
m_manufacturer.reset();
|
||||
m_year.reset();
|
||||
m_basename.reset();
|
||||
m_basename_noext.reset();
|
||||
m_filetype.reset();
|
||||
|
||||
m_full_software_name = NULL;
|
||||
m_software_info_ptr = NULL;
|
||||
m_software_part_ptr = NULL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
unload - main call to unload an image
|
||||
-------------------------------------------------*/
|
||||
|
||||
void legacy_image_device_base::unload()
|
||||
{
|
||||
if (is_loaded()) {
|
||||
call_unload();
|
||||
}
|
||||
clear();
|
||||
clear_error();
|
||||
}
|
||||
|
||||
int legacy_image_device_base::call_load()
|
||||
bool legacy_image_device_base::call_load()
|
||||
{
|
||||
device_image_load_func func = reinterpret_cast<device_image_load_func>(get_legacy_fct(DEVINFO_FCT_IMAGE_LOAD));
|
||||
if (func) {
|
||||
@ -639,7 +153,7 @@ bool legacy_image_device_base::call_softlist_load(char *swlist, char *swname, ro
|
||||
}
|
||||
}
|
||||
|
||||
int legacy_image_device_base::call_create(int format_type, option_resolution *format_options)
|
||||
bool legacy_image_device_base::call_create(int format_type, option_resolution *format_options)
|
||||
{
|
||||
device_image_create_func func = reinterpret_cast<device_image_create_func>(get_legacy_fct(DEVINFO_FCT_IMAGE_CREATE));
|
||||
if (func) {
|
||||
@ -667,17 +181,17 @@ void legacy_image_device_base::call_display_info()
|
||||
if (func) (*func)(*this);
|
||||
}
|
||||
|
||||
device_image_partialhash_func legacy_image_device_base::get_partial_hash()
|
||||
{
|
||||
return reinterpret_cast<device_image_partialhash_func>(get_legacy_fct(DEVINFO_FCT_IMAGE_PARTIAL_HASH));
|
||||
}
|
||||
|
||||
void legacy_image_device_base::call_get_devices()
|
||||
{
|
||||
device_image_get_devices_func func = reinterpret_cast<device_image_get_devices_func>(get_legacy_fct(DEVINFO_FCT_IMAGE_GET_DEVICES));
|
||||
if (func) (*func)(*this);
|
||||
}
|
||||
|
||||
device_image_partialhash_func legacy_image_device_base::get_partial_hash() const
|
||||
{
|
||||
return reinterpret_cast<device_image_partialhash_func>(get_legacy_fct(DEVINFO_FCT_IMAGE_PARTIAL_HASH));
|
||||
}
|
||||
|
||||
void *legacy_image_device_base::get_device_specific_call()
|
||||
{
|
||||
return (void*) get_legacy_fct(DEVINFO_FCT_DEVICE_SPECIFIC);
|
||||
|
@ -513,70 +513,33 @@ class legacy_image_device_base : public legacy_device_base,
|
||||
public device_image_interface
|
||||
{
|
||||
public:
|
||||
virtual iodevice_t image_type() const { return m_type; }
|
||||
virtual const char *image_type_name() const { return device_typename(m_type); }
|
||||
virtual iodevice_t image_type_direct() const { return static_cast<iodevice_t>(get_legacy_int(DEVINFO_INT_IMAGE_TYPE)); }
|
||||
virtual bool is_readable() const { return m_readable; }
|
||||
virtual bool is_writeable() const { return m_writeable; }
|
||||
virtual bool is_creatable() const { return m_creatable; }
|
||||
virtual bool must_be_loaded() const { return m_must_be_loaded; }
|
||||
virtual bool is_reset_on_load() const { return m_reset_on_load; }
|
||||
virtual bool has_partial_hash() const { return m_has_partial_hash; }
|
||||
virtual const char *image_interface() const { return m_interface_name; }
|
||||
virtual const char *file_extensions() const { return m_file_extensions; }
|
||||
virtual const char *instance_name() const { return m_instance_name; }
|
||||
virtual const char *brief_instance_name() const { return m_brief_instance_name; }
|
||||
virtual bool uses_file_extension(const char *file_extension) const;
|
||||
virtual const option_guide *create_option_guide() const { return m_create_option_guide; }
|
||||
virtual image_device_format *formatlist() const { return m_formatlist; }
|
||||
virtual device_image_partialhash_func get_partial_hash() const;
|
||||
|
||||
virtual bool load(const char *path);
|
||||
virtual bool finish_load();
|
||||
virtual void unload();
|
||||
virtual bool create(const char *path, const image_device_format *create_format, option_resolution *create_args);
|
||||
virtual bool load_software(char *swlist, char *swname, rom_entry *entry);
|
||||
|
||||
virtual int call_load();
|
||||
virtual bool call_load();
|
||||
virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry);
|
||||
virtual int call_create(int format_type, option_resolution *format_options);
|
||||
virtual bool call_create(int format_type, option_resolution *format_options);
|
||||
virtual void call_unload();
|
||||
virtual void call_display();
|
||||
virtual void call_display_info();
|
||||
virtual device_image_partialhash_func get_partial_hash();
|
||||
virtual device_image_partialhash_func get_partial_hash() const;
|
||||
virtual void call_get_devices();
|
||||
virtual void *get_device_specific_call();
|
||||
|
||||
virtual iodevice_t image_type() const { return static_cast<iodevice_t>(get_legacy_int(DEVINFO_INT_IMAGE_TYPE)); }
|
||||
|
||||
virtual bool is_readable() const { return get_legacy_int(DEVINFO_INT_IMAGE_READABLE)!=0; }
|
||||
virtual bool is_writeable() const { return get_legacy_int(DEVINFO_INT_IMAGE_WRITEABLE)!=0; }
|
||||
virtual bool is_creatable() const { return get_legacy_int(DEVINFO_INT_IMAGE_CREATABLE)!=0; }
|
||||
virtual bool must_be_loaded() const { return get_legacy_int(DEVINFO_INT_IMAGE_MUST_BE_LOADED)!=0; }
|
||||
virtual bool is_reset_on_load() const { return get_legacy_int(DEVINFO_INT_IMAGE_RESET_ON_LOAD)!=0; }
|
||||
virtual const char *image_interface() const { return get_legacy_string(DEVINFO_STR_IMAGE_INTERFACE); }
|
||||
virtual const char *file_extensions() const { return get_legacy_string(DEVINFO_STR_IMAGE_FILE_EXTENSIONS); }
|
||||
virtual const option_guide *create_option_guide() const { return reinterpret_cast<const option_guide *>(get_legacy_ptr(DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE)); }
|
||||
protected:
|
||||
// device overrides
|
||||
virtual void device_config_complete();
|
||||
|
||||
iodevice_t m_type;
|
||||
bool m_readable;
|
||||
bool m_writeable;
|
||||
bool m_creatable;
|
||||
bool m_must_be_loaded;
|
||||
bool m_reset_on_load;
|
||||
bool m_has_partial_hash;
|
||||
astring m_file_extensions;
|
||||
astring m_instance_name;
|
||||
astring m_brief_instance_name;
|
||||
astring m_interface_name;
|
||||
|
||||
/* creation info */
|
||||
const option_guide *m_create_option_guide;
|
||||
image_device_format *m_formatlist;
|
||||
|
||||
// construction/destruction
|
||||
legacy_image_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, device_get_config_func get_config);
|
||||
~legacy_image_device_base();
|
||||
// device_image_interface overrides
|
||||
bool load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args);
|
||||
void determine_open_plan(int is_create, UINT32 *open_plan);
|
||||
image_error_t load_image_by_path(UINT32 open_flags, const char *path);
|
||||
void clear();
|
||||
bool is_loaded();
|
||||
|
||||
bool m_is_loading;
|
||||
};
|
||||
|
||||
|
||||
|
@ -81,7 +81,9 @@ device_image_interface::device_image_interface(const machine_config &mconfig, de
|
||||
m_software_info_ptr(NULL),
|
||||
m_software_part_ptr(NULL),
|
||||
m_readonly(false),
|
||||
m_created(false)
|
||||
m_created(false),
|
||||
m_formatlist(NULL),
|
||||
m_is_loading(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -92,6 +94,15 @@ device_image_interface::device_image_interface(const machine_config &mconfig, de
|
||||
|
||||
device_image_interface::~device_image_interface()
|
||||
{
|
||||
image_device_format **formatptr = &m_formatlist;
|
||||
|
||||
/* free all entries */
|
||||
while (*formatptr != NULL)
|
||||
{
|
||||
image_device_format *entry = *formatptr;
|
||||
*formatptr = entry->m_next;
|
||||
global_free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -541,3 +552,456 @@ void device_image_interface::battery_save(const void *buffer, int length)
|
||||
astring_free(fname);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// uses_file_extension - update configuration
|
||||
// based on completed device setup
|
||||
//-------------------------------------------------
|
||||
|
||||
bool device_image_interface::uses_file_extension(const char *file_extension) const
|
||||
{
|
||||
bool result = FALSE;
|
||||
|
||||
if (file_extension[0] == '.')
|
||||
file_extension++;
|
||||
|
||||
/* find the extensions */
|
||||
astring extensions(file_extensions());
|
||||
char *ext = strtok((char*)extensions.cstr(),",");
|
||||
while (ext != NULL)
|
||||
{
|
||||
if (!mame_stricmp(ext, file_extension))
|
||||
{
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
ext = strtok (NULL, ",");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
IMAGE LOADING
|
||||
****************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
is_loaded - quick check to determine whether an
|
||||
image is loaded
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool device_image_interface::is_loaded()
|
||||
{
|
||||
return (m_file != NULL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
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)
|
||||
{
|
||||
file_error filerr = FILERR_NOT_FOUND;
|
||||
image_error_t err = IMAGE_ERROR_FILENOTFOUND;
|
||||
astring revised_path;
|
||||
|
||||
/* attempt to read the file */
|
||||
filerr = zippath_fopen(path, open_flags, &m_file, &revised_path);
|
||||
|
||||
/* did the open succeed? */
|
||||
switch(filerr)
|
||||
{
|
||||
case FILERR_NONE:
|
||||
/* success! */
|
||||
m_readonly = (open_flags & OPEN_FLAG_WRITE) ? 0 : 1;
|
||||
m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0;
|
||||
err = IMAGE_ERROR_SUCCESS;
|
||||
break;
|
||||
|
||||
case FILERR_NOT_FOUND:
|
||||
case FILERR_ACCESS_DENIED:
|
||||
/* file not found (or otherwise cannot open); continue */
|
||||
err = IMAGE_ERROR_FILENOTFOUND;
|
||||
break;
|
||||
|
||||
case FILERR_OUT_OF_MEMORY:
|
||||
/* out of memory */
|
||||
err = IMAGE_ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
|
||||
case FILERR_ALREADY_OPEN:
|
||||
/* this shouldn't happen */
|
||||
err = IMAGE_ERROR_ALREADYOPEN;
|
||||
break;
|
||||
|
||||
case FILERR_FAILURE:
|
||||
case FILERR_TOO_MANY_FILES:
|
||||
case FILERR_INVALID_DATA:
|
||||
default:
|
||||
/* other errors */
|
||||
err = IMAGE_ERROR_INTERNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if successful, set the file name */
|
||||
if (filerr == FILERR_NONE)
|
||||
set_image_filename(revised_path);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
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 */
|
||||
if (!is_create && is_readable() && is_writeable())
|
||||
open_plan[i++] = OPEN_FLAG_READ | OPEN_FLAG_WRITE;
|
||||
if (!is_create && !is_readable() && is_writeable())
|
||||
open_plan[i++] = OPEN_FLAG_WRITE;
|
||||
if (!is_create && is_readable())
|
||||
open_plan[i++] = OPEN_FLAG_READ;
|
||||
if (is_writeable() && is_creatable())
|
||||
open_plan[i++] = OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE;
|
||||
open_plan[i] = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
load_software - software image loading
|
||||
-------------------------------------------------*/
|
||||
bool device_image_interface::load_software(char *swlist, char *swname, rom_entry *start)
|
||||
{
|
||||
astring locationtag, breakstr("%");
|
||||
const rom_entry *region;
|
||||
astring regiontag;
|
||||
bool retVal = FALSE;
|
||||
for (region = start; region != NULL; region = rom_next_region(region))
|
||||
{
|
||||
/* loop until we hit the end of this region */
|
||||
const rom_entry *romp = region + 1;
|
||||
while (!ROMENTRY_ISREGIONEND(romp))
|
||||
{
|
||||
/* handle files */
|
||||
if (ROMENTRY_ISFILE(romp))
|
||||
{
|
||||
file_error filerr = FILERR_NOT_FOUND;
|
||||
|
||||
UINT32 crc = 0;
|
||||
bool has_crc = hash_collection(ROM_GETHASHDATA(romp)).crc(crc);
|
||||
|
||||
// attempt reading up the chain through the parents and create a locationtag astring in the format
|
||||
// " swlist % clonename % parentname "
|
||||
// below, we have the code to split the elements and to create paths to load from
|
||||
|
||||
software_list *software_list_ptr = software_list_open(device().machine().options(), swlist, FALSE, NULL);
|
||||
if (software_list_ptr)
|
||||
{
|
||||
for (software_info *swinfo = software_list_find(software_list_ptr, swname, NULL); swinfo != NULL; )
|
||||
{
|
||||
if (swinfo != NULL)
|
||||
{
|
||||
astring tmp(swinfo->shortname);
|
||||
locationtag.cat(tmp);
|
||||
locationtag.cat(breakstr);
|
||||
//printf("%s\n", locationtag.cstr());
|
||||
}
|
||||
const char *parentname = software_get_clone(device().machine().options(), swlist, swinfo->shortname);
|
||||
if (parentname != NULL)
|
||||
swinfo = software_list_find(software_list_ptr, parentname, NULL);
|
||||
else
|
||||
swinfo = NULL;
|
||||
}
|
||||
// strip the final '%'
|
||||
locationtag.del(locationtag.len() - 1, 1);
|
||||
software_list_close(software_list_ptr);
|
||||
}
|
||||
|
||||
if (software_get_support(device().machine().options(), swlist, swname) == SOFTWARE_SUPPORTED_PARTIAL)
|
||||
mame_printf_error("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist);
|
||||
|
||||
if (software_get_support(device().machine().options(), swlist, swname) == SOFTWARE_SUPPORTED_NO)
|
||||
mame_printf_error("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist);
|
||||
|
||||
// check if locationtag actually contains two locations separated by '%'
|
||||
// (i.e. check if we are dealing with a clone in softwarelist)
|
||||
astring tag2, tag3, tag4(locationtag), tag5;
|
||||
int separator = tag4.chr(0, '%');
|
||||
if (separator != -1)
|
||||
{
|
||||
// we are loading a clone through softlists, split the setname from the parentname
|
||||
tag5.cpysubstr(tag4, separator + 1, tag4.len() - separator + 1);
|
||||
tag4.del(separator, tag4.len() - separator);
|
||||
}
|
||||
|
||||
// prepare locations where we have to load from: list/parentname & list/clonename
|
||||
astring tag1(swlist);
|
||||
tag1.cat(PATH_SEPARATOR);
|
||||
tag2.cpy(tag1.cat(tag4));
|
||||
tag1.cpy(swlist);
|
||||
tag1.cat(PATH_SEPARATOR);
|
||||
tag3.cpy(tag1.cat(tag5));
|
||||
|
||||
if (tag5.chr(0, '%') != -1)
|
||||
fatalerror("We do not support clones of clones!\n");
|
||||
|
||||
// try to load from the available location(s):
|
||||
// - if we are not using lists, we have regiontag only;
|
||||
// - if we are using lists, we have: list/clonename, list/parentname, clonename, parentname
|
||||
// try to load from list/setname
|
||||
if ((m_mame_file == NULL) && (tag2.cstr() != NULL))
|
||||
filerr = common_process_file(device().machine().options(), tag2.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
// try to load from list/parentname
|
||||
if ((m_mame_file == NULL) && (tag3.cstr() != NULL))
|
||||
filerr = common_process_file(device().machine().options(), tag3.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
// try to load from setname
|
||||
if ((m_mame_file == NULL) && (tag4.cstr() != NULL))
|
||||
filerr = common_process_file(device().machine().options(), tag4.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
// try to load from parentname
|
||||
if ((m_mame_file == NULL) && (tag5.cstr() != NULL))
|
||||
filerr = common_process_file(device().machine().options(), tag5.cstr(), has_crc, crc, romp, &m_mame_file);
|
||||
|
||||
if (filerr == FILERR_NONE)
|
||||
{
|
||||
m_file = *m_mame_file;
|
||||
retVal = TRUE;
|
||||
}
|
||||
|
||||
break; // load first item for start
|
||||
}
|
||||
romp++; /* something else; skip */
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
load_internal - core image loading
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool device_image_interface::load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args)
|
||||
{
|
||||
UINT32 open_plan[4];
|
||||
int i;
|
||||
bool softload = FALSE;
|
||||
m_from_swlist = FALSE;
|
||||
|
||||
// if the path contains no period, we are using softlists, so we won't create an image
|
||||
astring pathstr(path);
|
||||
bool filename_has_period = (pathstr.rchr(0, '.') != -1) ? TRUE : FALSE;
|
||||
|
||||
/* first unload the image */
|
||||
unload();
|
||||
|
||||
/* clear any possible error messages */
|
||||
clear_error();
|
||||
|
||||
/* we are now loading */
|
||||
m_is_loading = TRUE;
|
||||
|
||||
/* record the filename */
|
||||
m_err = set_image_filename(path);
|
||||
|
||||
if (m_err)
|
||||
goto done;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
softload = load_software_part( this, path, &m_software_info_ptr, &m_software_part_ptr, &m_full_software_name );
|
||||
// if we had launched from softlist with a specified part, e.g. "shortname:part"
|
||||
// we would have recorded the wrong name, so record it again based on software_info
|
||||
if (m_software_info_ptr && m_software_info_ptr->shortname)
|
||||
m_err = set_image_filename(m_software_info_ptr->shortname);
|
||||
|
||||
m_from_swlist = TRUE;
|
||||
}
|
||||
|
||||
if (is_create || filename_has_period)
|
||||
{
|
||||
/* determine open plan */
|
||||
determine_open_plan(is_create, open_plan);
|
||||
|
||||
/* attempt to open the file in various ways */
|
||||
for (i = 0; !m_file && open_plan[i]; i++)
|
||||
{
|
||||
/* 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 */
|
||||
if ( m_software_info_ptr )
|
||||
{
|
||||
m_longname = m_software_info_ptr->longname;
|
||||
m_manufacturer = m_software_info_ptr->publisher;
|
||||
m_year = m_software_info_ptr->year;
|
||||
//m_playable = m_software_info_ptr->supported;
|
||||
}
|
||||
|
||||
/* did we fail to find the file? */
|
||||
if (!is_loaded() && !softload)
|
||||
{
|
||||
m_err = IMAGE_ERROR_FILENOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* call device load or create */
|
||||
m_create_format = create_format;
|
||||
m_create_args = create_args;
|
||||
|
||||
if (m_init_phase==FALSE) {
|
||||
m_err = (image_error_t)finish_load();
|
||||
if (m_err)
|
||||
goto done;
|
||||
}
|
||||
/* success! */
|
||||
|
||||
done:
|
||||
if (m_err!=0) {
|
||||
if (!m_init_phase)
|
||||
{
|
||||
if (device().machine().phase() == MACHINE_PHASE_RUNNING)
|
||||
popmessage("Error: Unable to %s image '%s': %s\n", is_create ? "create" : "load", path, error());
|
||||
else
|
||||
mame_printf_error("Error: Unable to %s image '%s': %s", is_create ? "create" : "load", path, error());
|
||||
}
|
||||
clear();
|
||||
}
|
||||
else {
|
||||
/* do we need to reset the CPU? only schedule it if load/create is successful */
|
||||
if (device().machine().time() > attotime::zero && is_reset_on_load())
|
||||
device().machine().schedule_hard_reset();
|
||||
else
|
||||
{
|
||||
if (!m_init_phase)
|
||||
{
|
||||
if (device().machine().phase() == MACHINE_PHASE_RUNNING)
|
||||
popmessage("Image '%s' was successfully %s.", path, is_create ? "created" : "loaded");
|
||||
else
|
||||
mame_printf_info("Image '%s' was successfully %s.\n", path, is_create ? "created" : "loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_err ? IMAGE_INIT_FAIL : IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
load - load an image into MESS
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool device_image_interface::load(const char *path)
|
||||
{
|
||||
return load_internal(path, FALSE, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
image_finish_load - special call - only use
|
||||
from core
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool device_image_interface::finish_load()
|
||||
{
|
||||
bool err = IMAGE_INIT_PASS;
|
||||
|
||||
if (m_is_loading)
|
||||
{
|
||||
image_checkhash();
|
||||
|
||||
if (m_from_swlist)
|
||||
call_display_info();
|
||||
|
||||
if (has_been_created() )// && get_legacy_fct(DEVINFO_FCT_IMAGE_CREATE) != NULL)
|
||||
{
|
||||
err = call_create(m_create_format, m_create_args);
|
||||
if (err)
|
||||
{
|
||||
if (!m_err)
|
||||
m_err = IMAGE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* using device load */
|
||||
err = call_load();
|
||||
if (err)
|
||||
{
|
||||
if (!m_err)
|
||||
m_err = IMAGE_ERROR_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_is_loading = FALSE;
|
||||
m_create_format = 0;
|
||||
m_create_args = NULL;
|
||||
m_init_phase = FALSE;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
create - create a image
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool device_image_interface::create(const char *path, const image_device_format *create_format, option_resolution *create_args)
|
||||
{
|
||||
int format_index = (create_format != NULL) ? create_format->m_index : 0;
|
||||
return load_internal(path, TRUE, format_index, create_args);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
clear - clear all internal data pertaining
|
||||
to an image
|
||||
-------------------------------------------------*/
|
||||
|
||||
void device_image_interface::clear()
|
||||
{
|
||||
if (m_mame_file)
|
||||
{
|
||||
global_free(m_mame_file);
|
||||
m_mame_file = NULL;
|
||||
m_file = NULL;
|
||||
} else {
|
||||
if (m_file)
|
||||
{
|
||||
core_fclose(m_file);
|
||||
m_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_image_name.reset();
|
||||
m_readonly = false;
|
||||
m_created = false;
|
||||
|
||||
m_longname.reset();
|
||||
m_manufacturer.reset();
|
||||
m_year.reset();
|
||||
m_basename.reset();
|
||||
m_basename_noext.reset();
|
||||
m_filetype.reset();
|
||||
|
||||
m_full_software_name = NULL;
|
||||
m_software_info_ptr = NULL;
|
||||
m_software_part_ptr = NULL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
unload - main call to unload an image
|
||||
-------------------------------------------------*/
|
||||
|
||||
void device_image_interface::unload()
|
||||
{
|
||||
if (is_loaded()) {
|
||||
call_unload();
|
||||
}
|
||||
clear();
|
||||
clear_error();
|
||||
}
|
||||
|
@ -158,51 +158,36 @@ public:
|
||||
device_image_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_image_interface();
|
||||
|
||||
virtual iodevice_t image_type() const = 0;
|
||||
virtual const char *image_type_name() const = 0;
|
||||
virtual iodevice_t image_type_direct() const = 0;
|
||||
virtual bool is_readable() const = 0;
|
||||
virtual bool is_writeable() const = 0;
|
||||
virtual bool is_creatable() const = 0;
|
||||
virtual bool must_be_loaded() const = 0;
|
||||
virtual bool is_reset_on_load() const = 0;
|
||||
virtual bool has_partial_hash() const = 0;
|
||||
virtual const char *image_interface() const = 0;
|
||||
virtual const char *file_extensions() const = 0;
|
||||
virtual const char *instance_name() const = 0;
|
||||
virtual const char *brief_instance_name() const = 0;
|
||||
virtual bool uses_file_extension(const char *file_extension) const = 0;
|
||||
virtual const option_guide *create_option_guide() const = 0;
|
||||
virtual image_device_format *formatlist() const = 0;
|
||||
|
||||
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 device_image_partialhash_func get_partial_hash() const = 0;
|
||||
virtual void device_compute_hash(hash_collection &hashes, const void *data, size_t length, const char *types) const;
|
||||
|
||||
virtual bool load(const char *path) = 0;
|
||||
virtual bool finish_load() = 0;
|
||||
virtual void unload() = 0;
|
||||
virtual bool load_software(char *swlist, char *swname, rom_entry *entry) = 0;
|
||||
|
||||
virtual int call_load() = 0;
|
||||
virtual bool call_load() = 0;
|
||||
virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry) = 0;
|
||||
virtual int call_create(int format_type, option_resolution *format_options) = 0;
|
||||
virtual bool call_create(int format_type, option_resolution *format_options) = 0;
|
||||
virtual void call_unload() = 0;
|
||||
virtual void call_display() = 0;
|
||||
virtual void call_display_info() = 0;
|
||||
virtual void call_get_devices() = 0;
|
||||
virtual void *get_device_specific_call() = 0;
|
||||
|
||||
virtual const image_device_format *device_get_indexed_creatable_format(int index);
|
||||
virtual const image_device_format *device_get_named_creatable_format(const char *format_name);
|
||||
virtual device_image_partialhash_func get_partial_hash() const = 0;
|
||||
virtual iodevice_t image_type() const = 0;
|
||||
virtual bool is_readable() const = 0;
|
||||
virtual bool is_writeable() const = 0;
|
||||
virtual bool is_creatable() const = 0;
|
||||
virtual bool must_be_loaded() const = 0;
|
||||
virtual bool is_reset_on_load() const = 0;
|
||||
virtual const char *image_interface() const = 0;
|
||||
virtual const char *file_extensions() const = 0;
|
||||
virtual const option_guide *create_option_guide() const = 0;
|
||||
|
||||
const image_device_format *device_get_indexed_creatable_format(int index);
|
||||
const image_device_format *device_get_named_creatable_format(const char *format_name);
|
||||
const option_guide *device_get_creation_option_guide() { return create_option_guide(); }
|
||||
const image_device_format *device_get_creatable_formats() { return formatlist(); }
|
||||
|
||||
virtual bool create(const char *path, const image_device_format *create_format, option_resolution *create_args) = 0;
|
||||
|
||||
|
||||
const char *error();
|
||||
void seterror(image_error_t err, const char *message);
|
||||
void message(const char *format, ...);
|
||||
@ -236,8 +221,8 @@ public:
|
||||
const software_info *software_entry() { return m_software_info_ptr; }
|
||||
const software_part *part_entry() { return m_software_part_ptr; }
|
||||
|
||||
virtual void set_working_directory(const char *working_directory) { m_working_directory = working_directory; }
|
||||
virtual const char * working_directory();
|
||||
void set_working_directory(const char *working_directory) { m_working_directory = working_directory; }
|
||||
const char * working_directory();
|
||||
|
||||
UINT8 *get_software_region(const char *tag);
|
||||
UINT32 get_software_region_length(const char *tag);
|
||||
@ -248,7 +233,28 @@ public:
|
||||
|
||||
void battery_load(void *buffer, int length, int fill);
|
||||
void battery_save(const void *buffer, int length);
|
||||
|
||||
const char *image_type_name() const { return device_typename(image_type()); }
|
||||
|
||||
|
||||
|
||||
const char *instance_name() const { return m_instance_name; }
|
||||
const char *brief_instance_name() const { return m_brief_instance_name; }
|
||||
bool uses_file_extension(const char *file_extension) const;
|
||||
image_device_format *formatlist() const { return m_formatlist; }
|
||||
|
||||
bool load(const char *path);
|
||||
bool finish_load();
|
||||
void unload();
|
||||
bool create(const char *path, const image_device_format *create_format, option_resolution *create_args);
|
||||
bool load_software(char *swlist, char *swname, rom_entry *entry);
|
||||
protected:
|
||||
bool load_internal(const char *path, bool is_create, int create_format, option_resolution *create_args);
|
||||
void determine_open_plan(int is_create, UINT32 *open_plan);
|
||||
image_error_t load_image_by_path(UINT32 open_flags, const char *path);
|
||||
void clear();
|
||||
bool is_loaded();
|
||||
|
||||
image_error_t set_image_filename(const char *filename);
|
||||
|
||||
void clear_error();
|
||||
@ -304,6 +310,14 @@ protected:
|
||||
option_resolution *m_create_args;
|
||||
|
||||
hash_collection m_hash;
|
||||
|
||||
astring m_brief_instance_name;
|
||||
astring m_instance_name;
|
||||
|
||||
/* creation info */
|
||||
image_device_format *m_formatlist;
|
||||
|
||||
bool m_is_loading;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user