summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Vas Crabb <cuavas@users.noreply.github.com>2016-08-01 12:43:22 +1000
committer GitHub <noreply@github.com>2016-08-01 12:43:22 +1000
commite2682ec4daae69e3519452446c6e16a6e0999ca6 (patch)
tree0bd731bd3601c6952945e4007053dc1747188356 /src
parent2c9966e3c965ad335bde409716b1b3a7a14a910e (diff)
parent7b7faffd0116ffb170763a105d25c980331a516e (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/emu/diimage.cpp148
-rw-r--r--src/emu/diimage.h6
-rw-r--r--src/emu/image.cpp42
-rw-r--r--src/frontend/mame/ui/floppycntrl.cpp2
4 files changed, 126 insertions, 72 deletions
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 4994ff5946c..f587ff80cc2 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -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
@@ -1069,6 +1029,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();
diff --git a/src/emu/diimage.h b/src/emu/diimage.h
index 71f332170af..25205e2547a 100644
--- a/src/emu/diimage.h
+++ b/src/emu/diimage.h
@@ -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;
diff --git a/src/emu/image.cpp b/src/emu/image.cpp
index 707c36ba0a5..129fc197717 100644
--- a/src/emu/image.cpp
+++ b/src/emu/image.cpp
@@ -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"
@@ -17,6 +19,13 @@
#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);
+
+ // 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? */
+ // 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());
}
}
diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp
index 1208f0b1181..21f8e28fe6a 100644
--- a/src/frontend/mame/ui/floppycntrl.cpp
+++ b/src/frontend/mame/ui/floppycntrl.cpp
@@ -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;
}