summaryrefslogtreecommitdiffstats
path: root/src/emu/diimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/diimage.cpp')
-rw-r--r--src/emu/diimage.cpp147
1 files changed, 62 insertions, 85 deletions
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 8cc849ee189..4ec5ff7898c 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -836,56 +836,44 @@ std::vector<u32> device_image_interface::determine_open_plan(bool is_create)
//-------------------------------------------------
-// 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 util::hash_collection &hashes, const util::hash_collection &acthashes)
-{
- osd_printf_error(" EXPECTED: %s\n", hashes.macro_string());
- osd_printf_error(" FOUND: %s\n", acthashes.macro_string());
-}
-
-
-//-------------------------------------------------
// 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, u32 explength, const util::hash_collection &hashes)
{
- int retVal = 0;
- if (file==nullptr) return 0;
+ int retval = 0;
+ if (!file)
+ return 0;
// verify length
u32 actlength = file->size();
if (explength != actlength)
{
osd_printf_error("%s WRONG LENGTH (expected: %d found: %d)\n", name, explength, actlength);
- retVal++;
+ retval++;
}
- // If there is no good dump known, write it
util::hash_collection &acthashes = file->hashes(hashes.hash_types().c_str());
if (hashes.flag(util::hash_collection::FLAG_NO_DUMP))
{
+ // If there is no good dump known, write it
osd_printf_error("%s NO GOOD DUMP KNOWN\n", name);
}
- // verify checksums
else if (hashes != acthashes)
{
// otherwise, it's just bad
osd_printf_error("%s WRONG CHECKSUMS:\n", name);
- dump_wrong_and_correct_checksums(hashes, acthashes);
- retVal++;
+ osd_printf_error(" EXPECTED: %s\n", hashes.macro_string());
+ osd_printf_error(" FOUND: %s\n", acthashes.macro_string());
+ retval++;
}
- // If it matches, but it is actually a bad dump, write it
else if (hashes.flag(util::hash_collection::FLAG_BAD_DUMP))
{
+ // If it matches, but it is actually a bad dump, write it
osd_printf_error("%s NEEDS REDUMP\n",name);
}
- return retVal;
+ return retval;
}
@@ -895,102 +883,91 @@ static int verify_length_and_hash(emu_file *file, const char *name, u32 explengt
bool device_image_interface::load_software(software_list_device &swlist, const char *swname, const rom_entry *start)
{
- std::string locationtag, breakstr("%");
- const rom_entry *region;
- bool retVal = false;
+ bool retval = false;
int warningcount = 0;
- for (region = start; region != nullptr; region = rom_next_region(region))
+ for (const rom_entry *region = start; region; region = rom_next_region(region))
{
// loop until we hit the end of this region
- const rom_entry *romp = region + 1;
- while (!ROMENTRY_ISREGIONEND(romp))
+ for (const rom_entry *romp = region + 1; !ROMENTRY_ISREGIONEND(romp); romp++)
{
// handle files
if (ROMENTRY_ISFILE(romp))
{
- osd_file::error filerr = osd_file::error::NOT_FOUND;
-
- u32 crc = 0;
- bool has_crc = util::hash_collection(ROM_GETHASHDATA(romp)).crc(crc);
-
- const software_info *swinfo = swlist.find(swname);
- if (swinfo == nullptr)
+ const software_info *const swinfo = swlist.find(swname);
+ if (!swinfo)
return false;
- u32 supported = swinfo->supported();
+ const u32 supported = swinfo->supported();
if (supported == SOFTWARE_SUPPORTED_PARTIAL)
osd_printf_error("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist.list_name());
if (supported == SOFTWARE_SUPPORTED_NO)
osd_printf_error("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name());
- // attempt reading up the chain through the parents and create a locationtag std::string in the format
- // " swlist % clonename % parentname "
- // below, we have the code to split the elements and to create paths to load from
+ u32 crc = 0;
+ const bool has_crc = util::hash_collection(ROM_GETHASHDATA(romp)).crc(crc);
+ std::vector<const software_info *> parents;
+ std::vector<std::string> searchpath;
- while (swinfo != nullptr)
+ // search <rompath>/<list>/<software> following parents
+ searchpath.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), swname));
+ for (const software_info *i = swinfo; i && !i->parentname().empty(); i = swlist.find(i->parentname()))
{
- locationtag.append(swinfo->shortname()).append(breakstr);
- swinfo = !swinfo->parentname().empty() ? swlist.find(swinfo->parentname()) : nullptr;
+ if (std::find(parents.begin(), parents.end(), i) != parents.end())
+ {
+ osd_printf_warning("WARNING: parent/clone relationships form a loop for software %s (in list %s)\n", swname, swlist.list_name());
+ break;
+ }
+ parents.emplace_back(i);
+ searchpath.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), i->parentname()));
}
- // strip the final '%'
- locationtag.erase(locationtag.length() - 1, 1);
+ // search <rompath>/<software> following parents
+ searchpath.emplace_back(swname);
+ parents.clear();
+ for (software_info const *i = swinfo; i && !i->parentname().empty(); i = swlist.find(i->parentname()))
+ {
+ if (std::find(parents.begin(), parents.end(), i) != parents.end())
+ break;
+ parents.emplace_back(i);
+ searchpath.emplace_back(i->parentname());
+ }
- // check if locationtag actually contains two locations separated by '%'
- // (i.e. check if we are dealing with a clone in softwarelist)
- std::string tag2, tag3, tag4(locationtag), tag5;
- int separator = tag4.find_first_of('%');
- if (separator != -1)
+ // for historical reasons, add the search path for the software list device's owner
+ const device_t *const listowner = swlist.owner();
+ if (listowner)
{
- // we are loading a clone through softlists, split the setname from the parentname
- tag5.assign(tag4.substr(separator + 1, tag4.length() - separator + 1));
- tag4.erase(separator, tag4.length() - separator);
+ std::vector<std::string> devsearch = listowner->searchpath();
+ for (std::string &path : devsearch)
+ searchpath.emplace_back(std::move(path));
}
- // prepare locations where we have to load from: list/parentname & list/clonename
- std::string tag1(swlist.list_name());
- tag1.append(PATH_SEPARATOR);
- tag2.assign(tag1.append(tag4));
- tag1.assign(swlist.list_name());
- tag1.append(PATH_SEPARATOR);
- tag3.assign(tag1.append(tag5));
-
- if (tag5.find_first_of('%') != -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 == nullptr) && (tag2.c_str() != nullptr))
- m_mame_file = common_process_file(device().machine().options(), tag2.c_str(), has_crc, crc, romp, filerr);
- // try to load from list/parentname
- if ((m_mame_file == nullptr) && (tag3.c_str() != nullptr))
- m_mame_file = common_process_file(device().machine().options(), tag3.c_str(), has_crc, crc, romp, filerr);
- // try to load from setname
- if ((m_mame_file == nullptr) && (tag4.c_str() != nullptr))
- m_mame_file = common_process_file(device().machine().options(), tag4.c_str(), has_crc, crc, romp, filerr);
- // try to load from parentname
- if ((m_mame_file == nullptr) && (tag5.c_str() != nullptr))
- m_mame_file = common_process_file(device().machine().options(), tag5.c_str(), has_crc, crc, romp, filerr);
-
- warningcount += verify_length_and_hash(m_mame_file.get(),ROM_GETNAME(romp),ROM_GETLENGTH(romp), util::hash_collection(ROM_GETHASHDATA(romp)));
+ // try to load the file
+ m_mame_file.reset(new emu_file(device().machine().options().media_path(), searchpath, OPEN_FLAG_READ));
+ m_mame_file->set_restrict_to_mediapath(1);
+ osd_file::error filerr;
+ if (has_crc)
+ filerr = m_mame_file->open(ROM_GETNAME(romp), crc);
+ else
+ filerr = m_mame_file->open(ROM_GETNAME(romp));
+ if (filerr != osd_file::error::NONE)
+ m_mame_file.reset();
+
+ warningcount += verify_length_and_hash(m_mame_file.get(), ROM_GETNAME(romp), ROM_GETLENGTH(romp), util::hash_collection(ROM_GETHASHDATA(romp)));
if (filerr == osd_file::error::NONE)
filerr = util::core_file::open_proxy(*m_mame_file, m_file);
if (filerr == osd_file::error::NONE)
- retVal = true;
+ retval = true;
break; // load first item for start
}
- romp++; /* something else; skip */
}
}
+
if (warningcount > 0)
- {
osd_printf_error("WARNING: the software item might not run correctly.\n");
- }
- return retVal;
+
+ return retval;
}