Merge pull request #1161 from npwoods/separate_softlist_image_load

Changed device_image_interface::load() so that it is no longer responsible for both loading images and softlist items
This commit is contained in:
Vas Crabb 2016-08-01 12:43:22 +10:00 committed by GitHub
commit e2682ec4da
4 changed files with 126 additions and 72 deletions

View File

@ -197,17 +197,8 @@ void device_image_interface::set_image_filename(const std::string &filename)
[](char c) { return (c == '\\') || (c == '/') || (c == ':'); });
if (iter != m_image_name.rend())
{
if (*iter == ':')
{
// temp workaround for softlists now that m_image_name contains the part name too (e.g. list:gamename:cart)
m_basename.assign(m_image_name.begin(), std::next(iter).base());
int tmploc = m_basename.find_last_of(':');
m_basename = m_basename.substr(tmploc + 1);
}
else
m_basename.assign(iter.base(), m_image_name.end());
}
m_basename.assign(iter.base(), m_image_name.end());
m_basename_noext = m_basename;
m_filetype = "";
auto loc = m_basename_noext.find_last_of('.');
@ -933,10 +924,6 @@ bool device_image_interface::load_internal(const std::string &path, bool is_crea
{
UINT32 open_plan[4];
int i;
bool softload = false;
// if the path contains no period, we are using softlists, so we won't create an image
bool filename_has_period = (path.find_last_of('.') != -1);
// first unload the image
unload();
@ -952,30 +939,7 @@ bool device_image_interface::load_internal(const std::string &path, bool is_crea
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
if (!filename_has_period && !just_load)
{
softload = load_software_part(path.c_str(), m_software_part_ptr);
if (softload)
{
m_software_info_ptr = &m_software_part_ptr->info();
m_software_list_name.assign(m_software_info_ptr->list().list_name());
m_full_software_name.assign(m_software_part_ptr->info().shortname());
// 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_full_software_name.empty())
set_image_filename(m_full_software_name);
// check if image should be read-only
const char *read_only = get_feature("read_only");
if (read_only && !strcmp(read_only, "true")) {
make_readonly();
}
}
}
if (is_create || filename_has_period)
if (is_create)
{
// determine open plan
determine_open_plan(is_create, open_plan);
@ -990,22 +954,8 @@ bool device_image_interface::load_internal(const std::string &path, bool is_crea
}
}
// Copy some image information when we have been loaded through a software list
if ( m_software_info_ptr )
{
// sanitize
if (m_software_info_ptr->longname().empty() || m_software_info_ptr->publisher().empty() || m_software_info_ptr->year().empty())
fatalerror("Each entry in an XML list must have all of the following fields: description, publisher, year!\n");
// store
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)
if (!is_loaded())
{
m_err = IMAGE_ERROR_FILENOTFOUND;
goto done;
@ -1039,10 +989,8 @@ done:
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
// do we need to reset the CPU? only schedule it if load/create is successful
if (!schedule_postload_hard_reset_if_needed())
{
if (!m_init_phase)
{
@ -1057,6 +1005,18 @@ done:
}
//-------------------------------------------------
// schedule_postload_hard_reset_if_needed
//-------------------------------------------------
bool device_image_interface::schedule_postload_hard_reset_if_needed()
{
bool postload_hard_reset_needed = device().machine().time() > attotime::zero && is_reset_on_load();
if (postload_hard_reset_needed)
device().machine().schedule_hard_reset();
return postload_hard_reset_needed;
}
//-------------------------------------------------
// load - load an image into MAME
@ -1068,6 +1028,76 @@ bool device_image_interface::load(const char *path)
}
//-------------------------------------------------
// load_software - loads a softlist item by name
//-------------------------------------------------
bool device_image_interface::load_software(const std::string &softlist_name)
{
// Prepare to load
unload();
clear_error();
m_is_loading = true;
// Check if there's a software list defined for this device and use that if we're not creating an image
bool softload = load_software_part(softlist_name.c_str(), m_software_part_ptr);
if (!softload)
{
m_is_loading = false;
return IMAGE_INIT_FAIL;
}
// set up softlist stuff
m_software_info_ptr = &m_software_part_ptr->info();
m_software_list_name.assign(m_software_info_ptr->list().list_name());
m_full_software_name.assign(m_software_part_ptr->info().shortname());
// specify image name with softlist-derived names
m_image_name = m_full_software_name;
m_basename = m_full_software_name;
m_basename_noext = m_full_software_name;
m_filetype = "";
// check if image should be read-only
const char *read_only = get_feature("read_only");
if (read_only && !strcmp(read_only, "true"))
{
make_readonly();
// Copy some image information when we have been loaded through a software list
if (m_software_info_ptr)
{
// sanitize
if (m_software_info_ptr->longname().empty() || m_software_info_ptr->publisher().empty() || m_software_info_ptr->year().empty())
fatalerror("Each entry in an XML list must have all of the following fields: description, publisher, year!\n");
// store
m_longname = m_software_info_ptr->longname();
m_manufacturer = m_software_info_ptr->publisher();
m_year = m_software_info_ptr->year();
}
}
// call finish_load if necessary
if (m_init_phase == false && finish_load())
return IMAGE_INIT_FAIL;
// do we need to reset the CPU? only schedule it if load is successful
if (!schedule_postload_hard_reset_if_needed())
{
if (!m_init_phase)
{
if (device().machine().phase() == MACHINE_PHASE_RUNNING)
device().popmessage("Image '%s' was successfully loaded.", softlist_name);
else
osd_printf_info("Image '%s' was successfully loaded.\n", softlist_name.c_str());
}
}
return IMAGE_INIT_PASS;
}
//-------------------------------------------------
// open_image_file - opening plain image file
//-------------------------------------------------
@ -1161,6 +1191,8 @@ void device_image_interface::clear()
m_image_name.clear();
m_readonly = false;
m_created = false;
m_create_format = 0;
m_create_args = nullptr;
m_longname.clear();
m_manufacturer.clear();

View File

@ -226,7 +226,12 @@ public:
bool uses_file_extension(const char *file_extension) const;
const formatlist_type &formatlist() const { return m_formatlist; }
// loads an image file
bool load(const char *path);
// loads a softlist item by name
bool load_software(const std::string &softlist_name);
bool open_image_file(emu_options &options);
bool finish_load();
void unload();
@ -300,6 +305,7 @@ protected:
private:
static image_error_t image_error_from_file_error(osd_file::error filerr);
bool schedule_postload_hard_reset_if_needed();
// creation info
formatlist_type m_formatlist;

View File

@ -2,13 +2,15 @@
// copyright-holders:Nathan Woods, Miodrag Milanovic
/***************************************************************************
image.c
image.cpp
Core image functions and definitions.
***************************************************************************/
#include <ctype.h>
#include <regex>
#include "emu.h"
#include "emuopts.h"
@ -16,6 +18,13 @@
#include "config.h"
#include "xmlfile.h"
//**************************************************************************
// STATIC VARIABLES
//**************************************************************************
static std::regex s_softlist_regex("\\w+\\:\\w+\\:\\w+");
//**************************************************************************
// IMAGE MANAGER
//**************************************************************************
@ -27,35 +36,42 @@
image_manager::image_manager(running_machine &machine)
: m_machine(machine)
{
/* make sure that any required devices have been allocated */
// make sure that any required devices have been allocated
for (device_image_interface &image : image_interface_iterator(machine.root_device()))
{
/* is an image specified for this image */
const char *image_name = machine.options().value(image.instance_name());
// ignore things not user loadable
if (!image.user_loadable())
continue;
if ((image_name != nullptr) && (image_name[0] != '\0'))
// is an image specified for this image
const char *image_name_ptr = machine.options().value(image.instance_name());
if ((image_name_ptr != nullptr) && (image_name_ptr[0] != '\0'))
{
/* mark init state */
std::string image_name(image_name_ptr);
// mark init state
image.set_init_phase();
/* try to load this image */
bool result = image.load(image_name);
// is this image really a softlist part?
bool is_softlist_part = std::regex_match(image_name, s_softlist_regex);
/* did the image load fail? */
// try to load this image
bool result = is_softlist_part
? image.load_software(image_name)
: image.load(image_name.c_str());
// did the image load fail?
if (result)
{
/* retrieve image error message */
// retrieve image error message
std::string image_err = std::string(image.error());
std::string image_basename(image_name);
/* unload all images */
// unload all images
unload_all();
fatalerror_exitcode(machine, EMU_ERR_DEVICE, "Device %s load (%s) failed: %s",
image.device().name(),
image_basename.c_str(),
image_name.c_str(),
image_err.c_str());
}
}

View File

@ -66,7 +66,7 @@ void menu_control_floppy_image::hook_load(std::string filename, bool softlist)
if (softlist)
{
machine().popmessage("When loaded from software list, the disk is Read-only.\n");
m_image.load(filename.c_str());
m_image.load_software(filename);
stack_pop();
return;
}