diff options
Diffstat (limited to 'src/emu/diimage.cpp')
-rw-r--r-- | src/emu/diimage.cpp | 147 |
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; } |