const rom_entry *rom_next_file(const rom_entry *romp) { romp++; while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp)) romp++; return ROMENTRY_ISREGIONEND(romp) ? NULL : romp; }
const rom_entry *rom_first_file(const rom_entry *romp) { romp++; while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp)) romp++; return ROMENTRY_ISREGIONEND(romp) ? nullptr : romp; }
const struct RomModule *rom_next_file(const struct RomModule *romp) { romp++; while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp)) romp++; return ROMENTRY_ISREGIONEND(romp) ? NULL : romp; }
/*------------------------------------------------- load_software - software image loading -------------------------------------------------*/ bool legacy_image_device_base::load_software(char *swlist, char *swname, rom_entry *start) { 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)) { UINT32 crc = 0; UINT8 crcbytes[4]; file_error filerr; bool has_crc = hash_data_extract_binary_checksum(ROM_GETHASHDATA(romp), HASH_CRC, crcbytes); if (has_crc) crc = (crcbytes[0] << 24) | (crcbytes[1] << 16) | (crcbytes[2] << 8) | crcbytes[3]; astring fname(swlist, PATH_SEPARATOR, swname, PATH_SEPARATOR, ROM_GETNAME(romp)); if (has_crc) filerr = mame_fopen_crc(libretro_content_directory, fname, crc, OPEN_FLAG_READ, &m_mame_file); else filerr = mame_fopen(libretro_content_directory, fname, OPEN_FLAG_READ, &m_mame_file); if (filerr == FILERR_NONE) { m_file = mame_core_file(m_mame_file); retVal = TRUE; } break; // load first item for start } romp++; /* something else; skip */ } } return retVal; }
/*------------------------------------------------- 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; ) { { 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; }
static void process_rom_entries(romload_private *romdata, const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, device_t *device, bool from_list) { UINT32 lastflags = 0; /* loop until we hit the end of this region */ while (!ROMENTRY_ISREGIONEND(romp)) { /* if this is a continue entry, it's invalid */ if (ROMENTRY_ISCONTINUE(romp)) fatalerror("Error in RomModule definition: ROM_CONTINUE not preceded by ROM_LOAD\n"); /* if this is an ignore entry, it's invalid */ if (ROMENTRY_ISIGNORE(romp)) fatalerror("Error in RomModule definition: ROM_IGNORE not preceded by ROM_LOAD\n"); /* if this is a reload entry, it's invalid */ if (ROMENTRY_ISRELOAD(romp)) fatalerror("Error in RomModule definition: ROM_RELOAD not preceded by ROM_LOAD\n"); /* handle fills */ if (ROMENTRY_ISFILL(romp)) fill_rom_data(romdata, romp++); /* handle copies */ else if (ROMENTRY_ISCOPY(romp)) copy_rom_data(romdata, romp++); /* handle files */ else if (ROMENTRY_ISFILE(romp)) { int irrelevantbios = (ROM_GETBIOSFLAGS(romp) != 0 && ROM_GETBIOSFLAGS(romp) != device->system_bios()); const rom_entry *baserom = romp; int explength = 0; /* open the file if it is a non-BIOS or matches the current BIOS */ LOG(("Opening ROM file: %s\n", ROM_GETNAME(romp))); astring tried_file_names; if (!irrelevantbios && !open_rom_file(romdata, regiontag, romp, tried_file_names, from_list)) handle_missing_file(romdata, romp, tried_file_names, CHDERR_NONE); /* loop until we run out of reloads */ do { /* loop until we run out of continues/ignores */ do { rom_entry modified_romp = *romp++; //int readresult; /* handle flag inheritance */ if (!ROM_INHERITSFLAGS(&modified_romp)) lastflags = modified_romp._flags; else modified_romp._flags = (modified_romp._flags & ~ROM_INHERITEDFLAGS) | lastflags; explength += ROM_GETLENGTH(&modified_romp); /* attempt to read using the modified entry */ if (!ROMENTRY_ISIGNORE(&modified_romp) && !irrelevantbios) /*readresult = */read_rom_data(romdata, parent_region, &modified_romp); } while (ROMENTRY_ISCONTINUE(romp) || ROMENTRY_ISIGNORE(romp)); /* if this was the first use of this file, verify the length and CRC */ if (baserom) { LOG(("Verifying length (%X) and checksums\n", explength)); verify_length_and_hash(romdata, ROM_GETNAME(baserom), explength, hash_collection(ROM_GETHASHDATA(baserom))); LOG(("Verify finished\n")); } /* reseek to the start and clear the baserom so we don't reverify */ if (romdata->file != NULL) romdata->file->seek(0, SEEK_SET); baserom = NULL; explength = 0; } while (ROMENTRY_ISRELOAD(romp)); /* close the file */ if (romdata->file != NULL) { LOG(("Closing ROM file\n")); global_free(romdata->file); romdata->file = NULL; } } else { romp++; /* something else; skip */ } } }
static void process_disk_entries(romload_private *romdata, const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag) { /* loop until we hit the end of this region */ for ( ; !ROMENTRY_ISREGIONEND(romp); romp++) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { open_chd *chd = global_alloc(open_chd(regiontag)); hash_collection hashes(ROM_GETHASHDATA(romp)); chd_error err; /* make the filename of the source */ astring filename(ROM_GETNAME(romp), ".chd"); /* first open the source drive */ LOG(("Opening disk image: %s\n", filename.cstr())); err = chd_error(open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, chd->orig_chd(), locationtag)); if (err != CHDERR_NONE) { handle_missing_file(romdata, romp, astring(), err); global_free(chd); continue; } /* get the header and extract the SHA1 */ hash_collection acthashes; acthashes.add_sha1(chd->orig_chd().sha1()); /* verify the hash */ if (hashes != acthashes) { romdata->errorstring.catprintf("%s WRONG CHECKSUMS:\n", filename.cstr()); dump_wrong_and_correct_checksums(romdata, hashes, acthashes); romdata->warnings++; } else if (hashes.flag(hash_collection::FLAG_BAD_DUMP)) { romdata->errorstring.catprintf("%s CHD NEEDS REDUMP\n", filename.cstr()); romdata->knownbad++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* try to open or create the diff */ err = open_disk_diff(romdata->machine().options(), romp, chd->orig_chd(), chd->diff_chd()); if (err != CHDERR_NONE) { romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err)); romdata->errors++; global_free(chd); continue; } } /* we're okay, add to the list of disks */ LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp))); romdata->machine().romload_data->chd_list.append(*chd); } } }
void rom_load_manager::process_disk_entries(const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag) { /* loop until we hit the end of this region */ for ( ; !ROMENTRY_ISREGIONEND(romp); romp++) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { auto chd = std::make_unique<open_chd>(regiontag); hash_collection hashes(ROM_GETHASHDATA(romp)); chd_error err; /* make the filename of the source */ std::string filename = std::string(ROM_GETNAME(romp)).append(".chd"); /* first open the source drive */ LOG(("Opening disk image: %s\n", filename.c_str())); err = chd_error(open_disk_image(machine().options(), &machine().system(), romp, chd->orig_chd(), locationtag)); if (err != CHDERR_NONE) { handle_missing_file(romp, std::string(), err); chd = nullptr; continue; } /* get the header and extract the SHA1 */ hash_collection acthashes; acthashes.add_sha1(chd->orig_chd().sha1()); /* verify the hash */ if (hashes != acthashes) { strcatprintf(m_errorstring, "%s WRONG CHECKSUMS:\n", filename.c_str()); dump_wrong_and_correct_checksums(hashes, acthashes); m_warnings++; } else if (hashes.flag(hash_collection::FLAG_BAD_DUMP)) { strcatprintf(m_errorstring, "%s CHD NEEDS REDUMP\n", filename.c_str()); m_knownbad++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* try to open or create the diff */ err = open_disk_diff(machine().options(), romp, chd->orig_chd(), chd->diff_chd()); if (err != CHDERR_NONE) { strcatprintf(m_errorstring, "%s DIFF CHD ERROR: %s\n", filename.c_str(), chd_file::error_string(err)); m_errors++; chd = nullptr; continue; } } /* we're okay, add to the list of disks */ LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp))); m_chd_list.push_back(std::move(chd)); } } }
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; int warningcount = 0; for (region = start; region != nullptr; 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)) { osd_file::error filerr = osd_file::error::NOT_FOUND; UINT32 crc = 0; bool has_crc = util::hash_collection(ROM_GETHASHDATA(romp)).crc(crc); const software_info *swinfo = swlist.find(swname); if (swinfo == nullptr) return false; UINT32 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().c_str()); if (supported == SOFTWARE_SUPPORTED_NO) osd_printf_error("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name().c_str()); // 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 while (swinfo != nullptr) { locationtag.append(swinfo->shortname()).append(breakstr); swinfo = !swinfo->parentname().empty() ? swlist.find(swinfo->parentname().c_str()) : nullptr; } // strip the final '%' locationtag.erase(locationtag.length() - 1, 1); // 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) { // 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); } // 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))); 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; 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; }
const struct RomModule *rom_first_chunk(const struct RomModule *romp) { return (ROMENTRY_ISFILE(romp)) ? romp : NULL; }
static int process_disk_entries(struct rom_load_data *romdata, const struct RomModule *romp) { /* loop until we hit the end of this region */ while (!ROMENTRY_ISREGIONEND(romp)) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { struct chd_file *source, *diff = NULL; struct chd_header header; char filename[1024], *c; char acthash[HASH_BUF_SIZE]; int err; /* make the filename of the source */ strcpy(filename, ROM_GETNAME(romp)); c = strrchr(filename, '.'); if (c) strcpy(c, ".chd"); else strcat(filename, ".chd"); /* first open the source drive */ debugload("Opening disk image: %s\n", filename); source = chd_open(filename, 0, NULL); if (!source) { if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s NOT FOUND\n", filename); romdata->errors++; romp++; continue; } /* get the header and extract the MD5/SHA1 */ header = *chd_get_header(source); hash_data_clear(acthash); hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5); hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1); /* verify the MD5 */ if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0)) { sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s WRONG CHECKSUMS:\n", filename); dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash); romdata->warnings++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* make the filename of the diff */ strcpy(filename, ROM_GETNAME(romp)); c = strrchr(filename, '.'); if (c) strcpy(c, ".dif"); else strcat(filename, ".dif"); /* try to open the diff */ debugload("Opening differencing image: %s\n", filename); diff = chd_open(filename, 1, source); if (!diff) { /* didn't work; try creating it instead */ debugload("Creating differencing image: %s\n", filename); err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source); if (err != CHDERR_NONE) { if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s: CAN'T CREATE DIFF FILE\n", filename); romdata->errors++; romp++; continue; } /* open the newly-created diff file */ debugload("Opening differencing image: %s\n", filename); diff = chd_open(filename, 1, source); if (!diff) { if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s: CAN'T OPEN DIFF FILE\n", filename); romdata->errors++; romp++; continue; } } } /* we're okay, set the handle */ debugload("Assigning to handle %d\n", DISK_GETINDEX(romp)); disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff; romp++; } } return 1; }
static int process_rom_entries(struct rom_load_data *romdata, const struct RomModule *romp) { UINT32 lastflags = 0; /* loop until we hit the end of this region */ while (!ROMENTRY_ISREGIONEND(romp)) { /* if this is a continue entry, it's invalid */ if (ROMENTRY_ISCONTINUE(romp)) { printf("Error in RomModule definition: ROM_CONTINUE not preceded by ROM_LOAD\n"); goto fatalerror; } /* if this is a reload entry, it's invalid */ if (ROMENTRY_ISRELOAD(romp)) { printf("Error in RomModule definition: ROM_RELOAD not preceded by ROM_LOAD\n"); goto fatalerror; } /* handle fills */ if (ROMENTRY_ISFILL(romp)) { if (!fill_rom_data(romdata, romp++)) goto fatalerror; } /* handle copies */ else if (ROMENTRY_ISCOPY(romp)) { if (!copy_rom_data(romdata, romp++)) goto fatalerror; } /* handle files */ else if (ROMENTRY_ISFILE(romp)) { if (!ROM_GETBIOSFLAGS(romp) || (ROM_GETBIOSFLAGS(romp) == (system_bios+1))) /* alternate bios sets */ { const struct RomModule *baserom = romp; int explength = 0; /* open the file */ debugload("Opening ROM file: %s\n", ROM_GETNAME(romp)); if (!open_rom_file(romdata, romp)) handle_missing_file(romdata, romp); /* loop until we run out of reloads */ do { /* loop until we run out of continues */ do { struct RomModule modified_romp = *romp++; int readresult; /* handle flag inheritance */ if (!ROM_INHERITSFLAGS(&modified_romp)) lastflags = modified_romp._flags; else modified_romp._flags = (modified_romp._flags & ~ROM_INHERITEDFLAGS) | lastflags; explength += ROM_GETLENGTH(&modified_romp); /* attempt to read using the modified entry */ readresult = read_rom_data(romdata, &modified_romp); if (readresult == -1) goto fatalerror; } while (ROMENTRY_ISCONTINUE(romp)); /* if this was the first use of this file, verify the length and CRC */ if (baserom) { debugload("Verifying length (%X) and checksums\n", explength); verify_length_and_hash(romdata, ROM_GETNAME(baserom), explength, ROM_GETHASHDATA(baserom)); debugload("Verify finished\n"); } /* reseek to the start and clear the baserom so we don't reverify */ if (romdata->file) mame_fseek(romdata->file, 0, SEEK_SET); baserom = NULL; explength = 0; } while (ROMENTRY_ISRELOAD(romp)); /* close the file */ if (romdata->file) { debugload("Closing ROM file\n"); mame_fclose(romdata->file); romdata->file = NULL; } } else { romp++; /* skip over file */ } } } return 1; /* error case */ fatalerror: if (romdata->file) mame_fclose(romdata->file); romdata->file = NULL; return 0; }
static void process_disk_entries(rom_load_data *romdata, const rom_entry *romp) { /* loop until we hit the end of this region */ while (!ROMENTRY_ISREGIONEND(romp)) { /* handle files */ if (ROMENTRY_ISFILE(romp)) { chd_file *source, *diff = NULL; chd_header header; char filename[1024]; char acthash[HASH_BUF_SIZE]; chd_error err; /* make the filename of the source */ sprintf(filename, "%s.chd", ROM_GETNAME(romp)); /* first open the source drive */ debugload("Opening disk image: %s\n", filename); err = open_disk_image(Machine->gamedrv, romp, &source); if (err != CHDERR_NONE) { if (err == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s NOT FOUND\n", filename); /* if this is NO_DUMP, keep going, though the system may not be able to handle it */ if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_NO_DUMP)) romdata->warnings++; else romdata->errors++; romp++; continue; } /* get the header and extract the MD5/SHA1 */ header = *chd_get_header(source); hash_data_clear(acthash); hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5); hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1); /* verify the MD5 */ if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0)) { sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s WRONG CHECKSUMS:\n", filename); dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash); romdata->warnings++; } else if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_BAD_DUMP)) { sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s CHD NEEDS REDUMP\n", filename); romdata->warnings++; } /* if not read-only, make the diff file */ if (!DISK_ISREADONLY(romp)) { /* make the filename of the diff */ sprintf(filename, "%s.dif", ROM_GETNAME(romp)); /* try to open the diff */ debugload("Opening differencing image: %s\n", filename); err = chd_open(filename, CHD_OPEN_READWRITE, source, &diff); if (err != CHDERR_NONE) { /* didn't work; try creating it instead */ debugload("Creating differencing image: %s\n", filename); err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source); if (err != CHDERR_NONE) { if (err == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s: CAN'T CREATE DIFF FILE\n", filename); romdata->errors++; romp++; continue; } /* open the newly-created diff file */ debugload("Opening differencing image: %s\n", filename); err = chd_open(filename, CHD_OPEN_READWRITE, source, &diff); if (err != CHDERR_NONE) { if (err == CHDERR_UNSUPPORTED_VERSION) sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename); else sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s: CAN'T OPEN DIFF FILE\n", filename); romdata->errors++; romp++; continue; } } } /* we're okay, set the handle */ debugload("Assigning to handle %d\n", DISK_GETINDEX(romp)); disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff; romp++; } } }
const rom_entry *rom_first_chunk(const rom_entry *romp) { return (ROMENTRY_ISFILE(romp)) ? romp : NULL; }
static int info_listsoftware(core_options *options, const char *gamename) { FILE *out = stdout; int nr_lists = 0; char ** lists = NULL; int list_idx = 0; /* First determine the maximum number of lists we might encounter */ for ( int drvindex = 0; drivers[drvindex] != NULL; drvindex++ ) { if ( mame_strwildcmp( gamename, drivers[drvindex]->name ) == 0 ) { /* allocate the machine config */ machine_config *config = global_alloc(machine_config(drivers[drvindex]->machine_config)); for (const device_config *dev = config->m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) { software_list_config *swlist = (software_list_config *)downcast<const legacy_device_config_base *>(dev)->inline_config(); for ( int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++ ) { if ( swlist->list_name[i] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)) nr_lists++; } } /* free the machine config */ global_free(config); } } lists = global_alloc_array( char *, nr_lists ); fprintf( out, "<?xml version=\"1.0\"?>\n" "<!DOCTYPE softwarelist [\n" "<!ELEMENT softwarelists (softwarelist*)>\n" "\t<!ELEMENT softwarelist (software+)>\n" "\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n" "\t\t<!ATTLIST softwarelist description CDATA #IMPLIED>\n" "\t\t<!ELEMENT software (description, year?, publisher, part*)>\n" "\t\t\t<!ATTLIST software name CDATA #REQUIRED>\n" "\t\t\t<!ATTLIST software cloneof CDATA #IMPLIED>\n" "\t\t\t<!ATTLIST software supported (yes|partial|no) \"yes\">\n" "\t\t\t<!ELEMENT description (#PCDATA)>\n" "\t\t\t<!ELEMENT year (#PCDATA)>\n" "\t\t\t<!ELEMENT publisher (#PCDATA)>\n" "\t\t\t<!ELEMENT part (dataarea*)>\n" "\t\t\t\t<!ATTLIST part name CDATA #REQUIRED>\n" "\t\t\t\t<!ATTLIST part interface CDATA #REQUIRED>\n" "\t\t\t\t<!ATTLIST part feature CDATA #IMPLIED>\n" "\t\t\t\t<!ELEMENT dataarea (rom*)>\n" "\t\t\t\t\t<!ATTLIST dataarea name CDATA #REQUIRED>\n" "\t\t\t\t\t<!ATTLIST dataarea size CDATA #REQUIRED>\n" "\t\t\t\t\t<!ATTLIST dataarea databits (8|16|32|64) \"8\">\n" "\t\t\t\t\t<!ATTLIST dataarea endian (big|little) \"little\">\n" "\t\t\t\t\t<!ELEMENT rom EMPTY>\n" "\t\t\t\t\t\t<!ATTLIST rom name CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom size CDATA #REQUIRED>\n" "\t\t\t\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom md5 CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n" "\t\t\t\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n" "\t\t\t\t\t\t<!ATTLIST rom loadflag (load16_byte|load16_word|load16_word_swap|load32_byte|load32_word|load32_word_swap|load32_dword|load64_word|load64_word_swap|reload) #IMPLIED>\n" "]>\n\n" "<softwarelists>\n" ); for ( int drvindex = 0; drivers[drvindex] != NULL; drvindex++ ) { if ( mame_strwildcmp( gamename, drivers[drvindex]->name ) == 0 ) { /* allocate the machine config */ machine_config *config = global_alloc(machine_config(drivers[drvindex]->machine_config)); for (const device_config *dev = config->m_devicelist.first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) { software_list_config *swlist = (software_list_config *)downcast<const legacy_device_config_base *>(dev)->inline_config(); for ( int i = 0; i < DEVINFO_STR_SWLIST_MAX - DEVINFO_STR_SWLIST_0; i++ ) { if ( swlist->list_name[i] && *swlist->list_name[i] && (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM)) { software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); if ( list ) { /* Verify if we have encountered this list before */ bool seen_before = false; for ( int l = 0; l < list_idx && !seen_before; l++ ) { if ( ! strcmp( swlist->list_name[i], lists[l] ) ) { seen_before = true; } } if ( ! seen_before ) { lists[list_idx] = core_strdup( swlist->list_name[i] ); list_idx++; fprintf(out, "\t<softwarelist name=\"%s\">\n", swlist->list_name[i] ); for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) { fprintf( out, "\t\t<software name=\"%s\"", swinfo->shortname ); if ( swinfo->parentname != NULL ) fprintf( out, " cloneof=\"%s\"", swinfo->parentname ); if ( swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL ) fprintf( out, " supported=\"partial\"" ); if ( swinfo->supported == SOFTWARE_SUPPORTED_NO ) fprintf( out, " supported=\"no\"" ); fprintf( out, ">\n" ); fprintf( out, "\t\t\t<description>%s</description>\n", xml_normalize_string(swinfo->longname) ); fprintf( out, "\t\t\t<year>%s</year>\n", xml_normalize_string( swinfo->year ) ); fprintf( out, "\t\t\t<publisher>%s</publisher>\n", xml_normalize_string( swinfo->publisher ) ); for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) { fprintf( out, "\t\t\t<part name=\"%s\"", part->name ); if ( part->interface_ ) fprintf( out, " interface=\"%s\"", part->interface_ ); // if ( part->feature ) // fprintf( out, " features=\"%s\"", part->feature ); fprintf( out, ">\n"); /* TODO: display rom region information */ for ( const rom_entry *region = part->romdata; region; region = rom_next_region( region ) ) { fprintf( out, "\t\t\t\t<dataarea name=\"%s\" size=\"%x\">\n", ROMREGION_GETTAG(region), ROMREGION_GETLENGTH(region) ); for ( const rom_entry *rom = rom_first_file( region ); rom && !ROMENTRY_ISREGIONEND(rom); rom++ ) { if ( ROMENTRY_ISFILE(rom) ) { fprintf( out, "\t\t\t\t\t<rom name=\"%s\" size=\"%d\"", xml_normalize_string(ROM_GETNAME(rom)), rom_file_size(rom) ); /* dump checksum information only if there is a known dump */ if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) { char checksum[HASH_BUF_SIZE]; int hashtype; /* iterate over hash function types and print out their values */ for (hashtype = 0; hashtype < HASH_NUM_FUNCTIONS; hashtype++) if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), 1 << hashtype, checksum)) fprintf(out, " %s=\"%s\"", hash_function_name(1 << hashtype), checksum); } fprintf( out, " offset=\"%x\"", ROM_GETOFFSET(rom) ); if ( hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP) ) fprintf( out, " status=\"baddump\"" ); if ( hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP) ) fprintf( out, " status=\"nodump\"" ); fprintf( out, "/>\n" ); } else if ( ROMENTRY_ISRELOAD(rom) ) { fprintf( out, "\t\t\t\t\t<rom size=\"%d\" offset=\"%x\" loadflag=\"reload\" />\n", ROM_GETLENGTH(rom), ROM_GETOFFSET(rom) ); } } fprintf( out, "\t\t\t\t</dataarea>\n" ); } fprintf( out, "\t\t\t</part>\n" ); } fprintf( out, "\t\t</software>\n" ); } fprintf(out, "\t</softwarelist>\n" ); } software_list_close( list ); } } } } global_free(config); } } fprintf( out, "</softwarelists>\n" ); global_free( lists ); return MAMERR_NONE; }