static int process_cartridge(device_image_interface *image, process_mode mode) { const rom_source *source; const rom_entry *romrgn, *roment; int result = 0; for (source = rom_first_source(image->device().machine().config()); source != NULL; source = rom_next_source(*source)) { for (romrgn = rom_first_region(*source); romrgn != NULL; romrgn = rom_next_region(romrgn)) { roment = romrgn + 1; while(!ROMENTRY_ISREGIONEND(roment)) { if (ROMENTRY_GETTYPE(roment) == ROMENTRYTYPE_CARTRIDGE) { astring regiontag; image->device().siblingtag(regiontag, roment->_hashdata); if (strcmp(regiontag.cstr(),image->device().tag())==0) { result |= load_cartridge(image, romrgn, roment, mode); /* if loading failed in any cart region, stop loading */ if (result) return result; } } roment++; } } } return IMAGE_INIT_PASS; }
static void match_roms(core_options *options, const char *hash, int length, int *found) { int drvindex; /* iterate over drivers */ for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) { machine_config *config = global_alloc(machine_config(drivers[drvindex]->machine_config)); const rom_entry *region, *rom; const rom_source *source; /* iterate over sources, regions and files within the region */ for (source = rom_first_source(drivers[drvindex], config); source != NULL; source = rom_next_source(drivers[drvindex], config, source)) for (region = rom_first_region(drivers[drvindex], source); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) if (hash_data_is_equal(hash, ROM_GETHASHDATA(rom), 0)) { int baddump = hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP); /* output information about the match */ if (*found != 0) mame_printf_info(" "); mame_printf_info("= %s%-20s %-10s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), drivers[drvindex]->name, drivers[drvindex]->description); (*found)++; } global_free(config); } softlist_match_roms( options, hash, length, found ); }
static int process_cartridge(mess_image *image, mame_file *file) { const rom_entry *romrgn, *roment; int position, result; romrgn = rom_first_region(Machine->gamedrv); while(romrgn) { roment = romrgn + 1; while(!ROMENTRY_ISREGIONEND(roment)) { if (is_cart_roment(roment)) { parse_rom_name(roment, &position, NULL); if (position == image_index_in_device(image)) { result = load_cartridge(romrgn, roment, file); if (!result) return result; } } roment++; } romrgn = rom_next_region(romrgn); } return INIT_PASS; }
int cli_info_listcrc(core_options *options, const char *gamename) { int drvindex, count = 0; /* iterate over drivers */ for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { machine_config *config = global_alloc(machine_config(drivers[drvindex]->machine_config)); const rom_entry *region, *rom; const rom_source *source; /* iterate over sources, regions, and then ROMs within the region */ for (source = rom_first_source(drivers[drvindex], config); source != NULL; source = rom_next_source(drivers[drvindex], config, source)) for (region = rom_first_region(drivers[drvindex], source); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { char hashbuf[HASH_BUF_SIZE]; /* if we have a CRC, display it */ if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), HASH_CRC, hashbuf)) mame_printf_info("%s %-12s %s\n", hashbuf, ROM_GETNAME(rom), drivers[drvindex]->description); } count++; global_free(config); } /* return an error if none found */ return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; }
BOOL DriverUsesRoms(int driver_index) { const struct GameDriver *gamedrv = drivers[driver_index]; const struct RomModule *region, *rom; for (region = rom_first_region(gamedrv); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) return TRUE; return FALSE; }
/* returns 1 if rom is defined in this set */ int audit_is_rom_used (const game_driver *gamedrv, const char* hash) { const rom_entry *region, *rom; for (region = rom_first_region(gamedrv); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) /* Compare all the available checksums */ if (hash_data_is_equal(ROM_GETHASHDATA(rom), hash, 0)) return 1; return 0; }
BOOL DriverIsHarddisk(int driver_index) { const struct RomModule *region; const struct GameDriver *gamedrv = drivers[driver_index]; for (region = rom_first_region(gamedrv); region; region = rom_next_region(region)) if (ROMREGION_ISDISKDATA(region)) return TRUE; return FALSE; }
/* returns 1 if rom is defined in this set */ int RomInSet (const struct GameDriver *gamedrv, const char* hash) { const struct RomModule *region, *rom; for (region = rom_first_region(gamedrv); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) /* Compare all the available checksums */ if (hash_data_is_equal(ROM_GETHASHDATA(rom), hash, 0)) return 1; return 0; }
media_auditor::summary media_auditor::audit_device(device_t *device, const char *validation) { // start fresh m_record_list.reset(); // store validation for later m_validation = validation; m_searchpath = device->shortname(); int found = 0; int required = 0; // now iterate over regions and ROMs within for (const rom_entry *region = rom_first_region(*device); region != NULL; region = rom_next_region(region)) { for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { hash_collection hashes(ROM_GETHASHDATA(rom)); // count the number of files with hashes if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && !ROM_ISOPTIONAL(rom)) { required++; } // audit a file audit_record *record = NULL; if (ROMREGION_ISROMDATA(region)) record = audit_one_rom(rom); // audit a disk else if (ROMREGION_ISDISKDATA(region)) record = audit_one_disk(rom); // count the number of files that are found. if (record != NULL && (record->status() == audit_record::STATUS_GOOD || record->status() == audit_record::STATUS_FOUND_INVALID)) { found++; } } } if (found == 0 && required > 0) { m_record_list.reset(); return NOTFOUND; } // return a summary return summarize(device->shortname()); }
void printromlist(const struct RomModule *romp,const char *basename) { const struct RomModule *region, *rom, *chunk; char buf[512]; if (!romp) return; #ifdef MESS if (!strcmp(basename,"nes")) return; #endif printf("This is the list of the ROMs required for driver \"%s\".\n" "Name Size Checksum\n",basename); for (region = romp; region; region = rom_next_region(region)) { for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { const char *name = ROM_GETNAME(rom); const char* hash = ROM_GETHASHDATA(rom); int length = -1; /* default is for disks! */ if (ROMREGION_ISROMDATA(region)) { length = 0; for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk)) length += ROM_GETLENGTH(chunk); } printf("%-12s ", name); if (length >= 0) printf("%7d",length); else printf(" "); if (!hash_data_has_info(hash, HASH_INFO_NO_DUMP)) { if (hash_data_has_info(hash, HASH_INFO_BAD_DUMP)) printf(" BAD"); hash_data_print(hash, 0, buf); printf(" %s", buf); } else printf(" NO GOOD DUMP KNOWN"); printf("\n"); } } }
/*------------------------------------------------- softlist_match_roms - scan for a matching software ROM by hash -------------------------------------------------*/ static void softlist_match_roms(core_options *options, const char *hash, int length, int *found) { int drvindex; /* iterate over drivers */ for (drvindex = 0; drivers[drvindex] != NULL; drvindex++) { 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] ) { software_list *list = software_list_open( options, swlist->list_name[i], FALSE, NULL ); for ( software_info *swinfo = software_list_find( list, "*", NULL ); swinfo != NULL; swinfo = software_list_find( list, "*", swinfo ) ) { for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) { for ( const rom_entry *region = part->romdata; region != NULL; region = rom_next_region(region) ) { for ( const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom) ) { if ( hash_data_is_equal(hash, ROM_GETHASHDATA(rom), 0) ) { int baddump = hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP); /* output information about the match */ if (*found != 0) mame_printf_info(" "); mame_printf_info("= %s%-20s %s:%s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), swlist->list_name[i], swinfo->shortname, swinfo->longname); (*found)++; } } } } } software_list_close( list ); } } } global_free(config); } }
device_t *media_auditor::find_shared_device(device_t &device, const char *name, const hash_collection &romhashes, UINT64 romlength) { bool dumped = !romhashes.flag(hash_collection::FLAG_NO_DUMP); // special case for non-root devices device_t *highest_device = NULL; if (device.owner() != NULL) { for (const rom_entry *region = rom_first_region(device); region != NULL; region = rom_next_region(region)) for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) if (ROM_GETLENGTH(rom) == romlength) { hash_collection hashes(ROM_GETHASHDATA(rom)); if ((dumped && hashes == romhashes) || (!dumped && ROM_GETNAME(rom) == name)) highest_device = &device; } } else { // iterate up the parent chain for (int drvindex = m_enumerator.find(m_enumerator.driver().parent); drvindex != -1; drvindex = m_enumerator.find(m_enumerator.driver(drvindex).parent)) { device_iterator deviter(m_enumerator.config(drvindex).root_device()); for (device_t *scandevice = deviter.first(); scandevice != NULL; scandevice = deviter.next()) for (const rom_entry *region = rom_first_region(*scandevice); region; region = rom_next_region(region)) for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) if (ROM_GETLENGTH(rom) == romlength) { hash_collection hashes(ROM_GETHASHDATA(rom)); if ((dumped && hashes == romhashes) || (!dumped && ROM_GETNAME(rom) == name)) highest_device = scandevice; } } } return highest_device; }
static int count_roms(const struct RomModule *romp) { const struct RomModule *region, *rom; int count = 0; /* determine the correct biosset to load based on options.bios string */ int this_bios = determine_bios_rom(Machine->gamedrv->bios); /* loop over regions, then over files */ for (region = romp; region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) if (!ROM_GETBIOSFLAGS(romp) || (ROM_GETBIOSFLAGS(romp) == (this_bios+1))) /* alternate bios sets */ count++; /* return the total count */ return count; }
int media_auditor::also_used_by_parent(const hash_collection &romhashes) { // iterate up the parent chain for (int drvindex = m_enumerator.find(m_enumerator.driver().parent); drvindex != -1; drvindex = m_enumerator.find(m_enumerator.driver(drvindex).parent)) // see if the parent has the same ROM or not for (const rom_source *source = rom_first_source(m_enumerator.config(drvindex)); source != NULL; source = rom_next_source(*source)) for (const rom_entry *region = rom_first_region(*source); region; region = rom_next_region(region)) for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { hash_collection hashes(ROM_GETHASHDATA(rom)); if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && hashes == romhashes) return drvindex; } // nope, return -1 return -1; }
void rom_load_manager::count_roms() { const rom_entry *region, *rom; /* start with 0 */ m_romstotal = 0; m_romstotalsize = 0; /* loop over regions, then over files */ for (device_t &device : device_iterator(machine().config().root_device())) for (region = rom_first_region(device); region != nullptr; region = rom_next_region(region)) for (rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom)) if (ROM_GETBIOSFLAGS(rom) == 0 || ROM_GETBIOSFLAGS(rom) == device.system_bios()) { m_romstotal++; m_romstotalsize += rom_file_size(rom); } }
static void count_roms(romload_private *romdata) { const rom_entry *region, *rom; /* start with 0 */ romdata->romstotal = 0; romdata->romstotalsize = 0; /* loop over regions, then over files */ device_iterator deviter(romdata->machine().config().root_device()); for (device_t *device = deviter.first(); device != NULL; device = deviter.next()) for (region = rom_first_region(*device); region != NULL; region = rom_next_region(region)) for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) if (ROM_GETBIOSFLAGS(rom) == 0 || ROM_GETBIOSFLAGS(rom) == device->system_bios()) { romdata->romstotal++; romdata->romstotalsize += rom_file_size(rom); } }
/*------------------------------------------------- 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; }
chd_error open_disk_image(const game_driver *gamedrv, const rom_entry *romp, chd_file **image) { const game_driver *drv; const rom_entry *region, *rom; const char *fname; chd_error err; /* attempt to open the properly named file */ fname = assemble_2_strings(ROM_GETNAME(romp), ".chd"); err = chd_open(fname, CHD_OPEN_READ, NULL, image); free((void *)fname); /* if that worked, we're done */ if (err == CHDERR_NONE) return err; /* otherwise, look at our parents for a CHD with an identical checksum */ /* and try to open that */ for (drv = gamedrv; drv != NULL; drv = driver_get_clone(drv)) for (region = rom_first_region(drv); region != NULL; region = rom_next_region(region)) if (ROMREGION_ISDISKDATA(region)) for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) /* look for a differing name but with the same hash data */ if (strcmp(ROM_GETNAME(romp), ROM_GETNAME(rom)) != 0 && hash_data_is_equal(ROM_GETHASHDATA(romp), ROM_GETHASHDATA(rom), 0)) { fname = assemble_2_strings(ROM_GETNAME(rom), ".chd"); err = chd_open(fname, CHD_OPEN_READ, NULL, image); free((void *)fname); /* if that worked, we're done */ if (err == CHDERR_NONE) return err; } return err; }
/* Identifies a rom from from this checksum */ static void match_roms(const struct GameDriver *driver,const char* hash,int *found) { const struct RomModule *region, *rom; for (region = rom_first_region(driver); region; region = rom_next_region(region)) { for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { if (hash_data_is_equal(hash, ROM_GETHASHDATA(rom), 0)) { char baddump = hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP); if (!silentident) { if (*found != 0) fprintf(stdout_file, " "); fprintf(stdout_file, "= %s%-12s %s\n",baddump ? "(BAD) " : "",ROM_GETNAME(rom),driver->description); } (*found)++; } } } }
static void match_roms(const char *hash, int length, int *found) { int drvindex; /* iterate over drivers */ for (drvindex = 0; drivers[drvindex]; drvindex++) { const rom_entry *region, *rom; /* iterate over regions and files within the region */ for (region = rom_first_region(drivers[drvindex]); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) if (hash_data_is_equal(hash, ROM_GETHASHDATA(rom), 0)) { int baddump = hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP); /* output information about the match */ if (*found != 0) mame_printf_info(" "); mame_printf_info("= %s%-20s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), drivers[drvindex]->description); (*found)++; } } }
static int rom_used_by_parent(const game_driver *gamedrv, const rom_entry *romentry, const game_driver **parent) { const char *hash = ROM_GETHASHDATA(romentry); const game_driver *drv; /* iterate up the parent chain */ for (drv = driver_get_clone(gamedrv); drv != NULL; drv = driver_get_clone(drv)) { const rom_entry *region; const rom_entry *rom; /* see if the parent has the same ROM or not */ for (region = rom_first_region(drv, NULL); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) if (hash_data_is_equal(ROM_GETHASHDATA(rom), hash, 0)) { if (parent != NULL) *parent = drv; return TRUE; } } return FALSE; }
int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_entry *romp, chd_file &image_chd, const char *locationtag) { emu_file image_file(options.media_path(), OPEN_FLAG_READ); const rom_entry *region, *rom; file_error filerr; chd_error err; /* attempt to open the properly named file, scanning up through parent directories */ filerr = FILERR_NOT_FOUND; for (int searchdrv = driver_list::find(*gamedrv); searchdrv != -1 && filerr != FILERR_NONE; searchdrv = driver_list::clone(searchdrv)) filerr = common_process_file(options, driver_list::driver(searchdrv).name, ".chd", romp, image_file); if (filerr != FILERR_NONE) filerr = common_process_file(options, NULL, ".chd", romp, image_file); /* look for the disk in the locationtag too */ if (filerr != FILERR_NONE && locationtag != NULL) { // check if we are dealing with softwarelists. if so, locationtag // is actually a concatenation of: listname + setname + parentname // separated by '%' (parentname being present only for clones) astring tag1(locationtag), tag2, tag3, tag4, tag5; bool is_list = FALSE; bool has_parent = FALSE; int separator1 = tag1.chr(0, '%'); if (separator1 != -1) { is_list = TRUE; // we are loading through softlists, split the listname from the regiontag tag4.cpysubstr(tag1, separator1 + 1, tag1.len() - separator1 + 1); tag1.del(separator1, tag1.len() - separator1); tag1.cat(PATH_SEPARATOR); // check if we are loading a clone (if this is the case also tag1 have a separator '%') int separator2 = tag4.chr(0, '%'); if (separator2 != -1) { has_parent = TRUE; // we are loading a clone through softlists, split the setname from the parentname tag5.cpysubstr(tag4, separator2 + 1, tag4.len() - separator2 + 1); tag4.del(separator2, tag4.len() - separator2); } // prepare locations where we have to load from: list/parentname (if any) & list/clonename astring swlist(tag1.cstr()); tag2.cpy(swlist.cat(tag4)); if (has_parent) { swlist.cpy(tag1); tag3.cpy(swlist.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 locationtag only; // - if we are using lists, we have: list/clonename, list/parentname, clonename, parentname if (!is_list) filerr = common_process_file(options, locationtag, ".chd", romp, image_file); else { // try to load from list/setname if ((filerr != FILERR_NONE) && (tag2.cstr() != NULL)) filerr = common_process_file(options, tag2.cstr(), ".chd", romp, image_file); // try to load from list/parentname (if any) if ((filerr != FILERR_NONE) && has_parent && (tag3.cstr() != NULL)) filerr = common_process_file(options, tag3.cstr(), ".chd", romp, image_file); // try to load from setname if ((filerr != FILERR_NONE) && (tag4.cstr() != NULL)) filerr = common_process_file(options, tag4.cstr(), ".chd", romp, image_file); // try to load from parentname (if any) if ((filerr != FILERR_NONE) && has_parent && (tag5.cstr() != NULL)) filerr = common_process_file(options, tag5.cstr(), ".chd", romp, image_file); // only for CHD we also try to load from list/ if ((filerr != FILERR_NONE) && (tag1.cstr() != NULL)) { tag1.del(tag1.len() - 1, 1); // remove the PATH_SEPARATOR filerr = common_process_file(options, tag1.cstr(), ".chd", romp, image_file); } } } /* did the file open succeed? */ if (filerr == FILERR_NONE) { astring fullpath(image_file.fullpath()); image_file.close(); /* try to open the CHD */ err = image_chd.open(fullpath); if (err == CHDERR_NONE) return err; } else err = CHDERR_FILE_NOT_FOUND; /* otherwise, look at our parents for a CHD with an identical checksum */ /* and try to open that */ hash_collection romphashes(ROM_GETHASHDATA(romp)); for (int drv = driver_list::find(*gamedrv); drv != -1; drv = driver_list::clone(drv)) { machine_config config(driver_list::driver(drv), options); device_iterator deviter(config.root_device()); for (device_t *device = deviter.first(); device != NULL; device = deviter.next()) for (region = rom_first_region(*device); region != NULL; region = rom_next_region(region)) if (ROMREGION_ISDISKDATA(region)) for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) /* look for a differing name but with the same hash data */ if (strcmp(ROM_GETNAME(romp), ROM_GETNAME(rom)) != 0 && romphashes == hash_collection(ROM_GETHASHDATA(rom))) { /* attempt to open the properly named file, scanning up through parent directories */ filerr = FILERR_NOT_FOUND; for (int searchdrv = drv; searchdrv != -1 && filerr != FILERR_NONE; searchdrv = driver_list::clone(searchdrv)) filerr = common_process_file(options, driver_list::driver(searchdrv).name, ".chd", rom, image_file); if (filerr != FILERR_NONE) filerr = common_process_file(options, NULL, ".chd", rom, image_file); /* did the file open succeed? */ if (filerr == FILERR_NONE) { astring fullpath(image_file.fullpath()); image_file.close(); /* try to open the CHD */ err = image_chd.open(fullpath); if (err == CHDERR_NONE) return err; } } } return err; }
void load_software_part_region(device_t &device, software_list_device &swlist, const char *swname, const rom_entry *start_region) { astring locationtag(swlist.list_name()), breakstr("%"); romload_private *romdata = device.machine().romload_data; const rom_entry *region; astring regiontag; romdata->errorstring.reset(); romdata->softwarningstring.reset(); romdata->romstotal = 0; romdata->romstotalsize = 0; romdata->romsloadedsize = 0; software_info *swinfo = swlist.find(swname); if (swinfo != NULL) { UINT32 supported = swinfo->supported(); if (supported == SOFTWARE_SUPPORTED_PARTIAL) { romdata->errorstring.catprintf("WARNING: support for software %s (in list %s) is only partial\n", swname, swlist.list_name()); romdata->softwarningstring.catprintf("Support for software %s (in list %s) is only partial\n", swname, swlist.list_name()); } if (supported == SOFTWARE_SUPPORTED_NO) { romdata->errorstring.catprintf("WARNING: support for software %s (in list %s) is only preliminary\n", swname, swlist.list_name()); romdata->softwarningstring.catprintf("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 astring in the format // " swlist % clonename % parentname " // open_rom_file contains the code to split the elements and to create paths to load from locationtag.cat(breakstr); while (swinfo != NULL) { locationtag.cat(swinfo->shortname()).cat(breakstr); const char *parentname = swinfo->parentname(); swinfo = (parentname != NULL) ? swlist.find(parentname) : NULL; } // strip the final '%' locationtag.del(locationtag.len() - 1, 1); } /* loop until we hit the end */ for (region = start_region; region != NULL; region = rom_next_region(region)) { UINT32 regionlength = ROMREGION_GETLENGTH(region); device.subtag(regiontag, ROMREGION_GETTAG(region)); LOG(("Processing region \"%s\" (length=%X)\n", regiontag.cstr(), regionlength)); /* the first entry must be a region */ assert(ROMENTRY_ISREGION(region)); /* if this is a device region, override with the device width and endianness */ endianness_t endianness = ROMREGION_ISBIGENDIAN(region) ? ENDIANNESS_BIG : ENDIANNESS_LITTLE; UINT8 width = ROMREGION_GETWIDTH(region) / 8; memory_region *memregion = romdata->machine().root_device().memregion(regiontag); if (memregion != NULL) { if (romdata->machine().device(regiontag) != NULL) normalize_flags_for_device(romdata->machine(), regiontag, width, endianness); /* clear old region (todo: should be moved to an image unload function) */ romdata->machine().memory().region_free(memregion->name()); } /* remember the base and length */ romdata->region = romdata->machine().memory().region_alloc(regiontag, regionlength, width, endianness); LOG(("Allocated %X bytes @ %p\n", romdata->region->bytes(), romdata->region->base())); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(romdata->region->base(), ROMREGION_GETERASEVAL(region), romdata->region->bytes()); /* or if it's sufficiently small (<= 4MB) */ else if (romdata->region->bytes() <= 0x400000) memset(romdata->region->base(), 0, romdata->region->bytes()); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(romdata->machine(), romdata->region->base(), romdata->region->bytes()); #endif /* update total number of roms */ for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) { romdata->romstotal++; romdata->romstotalsize += rom_file_size(rom); } /* now process the entries in the region */ if (ROMREGION_ISROMDATA(region)) process_rom_entries(romdata, locationtag, region, region + 1, &device, TRUE); else if (ROMREGION_ISDISKDATA(region)) process_disk_entries(romdata, core_strdup(regiontag.cstr()), region, region + 1, locationtag); } /* now go back and post-process all the regions */ for (region = start_region; region != NULL; region = rom_next_region(region)) { device.subtag(regiontag, ROMREGION_GETTAG(region)); region_post_process(romdata, regiontag.cstr(), ROMREGION_ISINVERTED(region)); } /* display the results and exit */ display_rom_load_results(romdata, TRUE); }
void rom_load_manager::process_region_list() { std::string regiontag; /* loop until we hit the end */ device_iterator deviter(machine().root_device()); for (device_t *device = deviter.first(); device != nullptr; device = deviter.next()) for (const rom_entry *region = rom_first_region(*device); region != nullptr; region = rom_next_region(region)) { UINT32 regionlength = ROMREGION_GETLENGTH(region); regiontag = rom_region_name(*device, region); LOG(("Processing region \"%s\" (length=%X)\n", regiontag.c_str(), regionlength)); /* the first entry must be a region */ assert(ROMENTRY_ISREGION(region)); if (ROMREGION_ISROMDATA(region)) { /* if this is a device region, override with the device width and endianness */ UINT8 width = ROMREGION_GETWIDTH(region) / 8; endianness_t endianness = ROMREGION_ISBIGENDIAN(region) ? ENDIANNESS_BIG : ENDIANNESS_LITTLE; if (machine().device(regiontag.c_str()) != nullptr) normalize_flags_for_device(machine(), regiontag.c_str(), width, endianness); /* remember the base and length */ m_region = machine().memory().region_alloc(regiontag.c_str(), regionlength, width, endianness); LOG(("Allocated %X bytes @ %p\n", m_region->bytes(), m_region->base())); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(m_region->base(), ROMREGION_GETERASEVAL(region), m_region->bytes()); /* or if it's sufficiently small (<= 4MB) */ else if (m_region->bytes() <= 0x400000) memset(m_region->base(), 0, m_region->bytes()); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(m_region->base(), m_region->bytes()); #endif /* now process the entries in the region */ process_rom_entries(device->shortname().c_str(), region, region + 1, device, FALSE); } else if (ROMREGION_ISDISKDATA(region)) process_disk_entries(regiontag.c_str(), region, region + 1, nullptr); } /* now go back and post-process all the regions */ for (device_t *device = deviter.first(); device != nullptr; device = deviter.next()) for (const rom_entry *region = rom_first_region(*device); region != nullptr; region = rom_next_region(region)) { regiontag = rom_region_name(*device, region); region_post_process(regiontag.c_str(), ROMREGION_ISINVERTED(region)); } /* and finally register all per-game parameters */ for (device_t *device = deviter.first(); device != nullptr; device = deviter.next()) for (const rom_entry *param = rom_first_parameter(*device); param != nullptr; param = rom_next_parameter(param)) { regiontag = rom_parameter_name(*device, param); machine().parameters().add(regiontag, rom_parameter_value(param)); } }
media_auditor::summary media_auditor::audit_media(const char *validation) { // start fresh m_record_list.reset(); // store validation for later m_validation = validation; // temporary hack until romload is update: get the driver path and support it for // all searches const char *driverpath = m_enumerator.config().devicelist().find("root")->searchpath(); // iterate over ROM sources and regions int found = 0; int required = 0; int sharedFound = 0; int sharedRequired = 0; for (const rom_source *source = rom_first_source(m_enumerator.config()); source != NULL; source = rom_next_source(*source)) { // determine the search path for this source and iterate through the regions m_searchpath = source->searchpath(); // also determine if this is the driver's specific ROMs or not bool source_is_gamedrv = (dynamic_cast<const driver_device *>(source) != NULL); // now iterate over regions and ROMs within for (const rom_entry *region = rom_first_region(*source); region != NULL; region = rom_next_region(region)) { // temporary hack: add the driver path & region name astring combinedpath(source->searchpath(), ";", driverpath); if(ROMREGION_ISLOADBYNAME(region)) { combinedpath=combinedpath.cat(";"); combinedpath=combinedpath.cat(ROMREGION_GETTAG(region)); } m_searchpath = combinedpath; for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { hash_collection hashes(ROM_GETHASHDATA(rom)); bool shared = also_used_by_parent(hashes) >= 0; // if a dump exists, then at least one entry is required if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) { required++; if (shared) { sharedRequired++; } } // audit a file audit_record *record = NULL; if (ROMREGION_ISROMDATA(region)) record = audit_one_rom(rom); // audit a disk else if (ROMREGION_ISDISKDATA(region)) record = audit_one_disk(rom); // skip if no record if (record == NULL) continue; // if we got a record back, if (record->status() != audit_record::STATUS_NOT_FOUND && source_is_gamedrv) { found++; if (shared) { sharedFound++; } } } } } // if we found nothing unique to this set & the set needs roms that aren't in the parent or the parent isn't found either, then we don't have the set at all if (found == sharedFound && required > 0 && (required != sharedRequired || sharedFound == 0)) m_record_list.reset(); // return a summary return summarize(); }
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; }
media_auditor::summary media_auditor::audit_media(const char *validation) { // start fresh m_record_list.reset(); // store validation for later m_validation = validation; // temporary hack until romload is update: get the driver path and support it for // all searches const char *driverpath = m_enumerator.config().root_device().searchpath(); int found = 0; int required = 0; int shared_found = 0; int shared_required = 0; // iterate over devices and regions device_iterator deviter(m_enumerator.config().root_device()); for (device_t *device = deviter.first(); device != nullptr; device = deviter.next()) { // determine the search path for this source and iterate through the regions m_searchpath = device->searchpath(); // now iterate over regions and ROMs within for (const rom_entry *region = rom_first_region(*device); region != nullptr; region = rom_next_region(region)) { // temporary hack: add the driver path & region name std::string combinedpath = std::string(device->searchpath()).append(";").append(driverpath); if (device->shortname()) combinedpath.append(";").append(device->shortname()); m_searchpath = combinedpath.c_str(); for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { const char *name = ROM_GETNAME(rom); hash_collection hashes(ROM_GETHASHDATA(rom)); device_t *shared_device = find_shared_device(*device, name, hashes, ROM_GETLENGTH(rom)); // count the number of files with hashes if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && !ROM_ISOPTIONAL(rom)) { required++; if (shared_device != nullptr) shared_required++; } // audit a file audit_record *record = nullptr; if (ROMREGION_ISROMDATA(region)) record = audit_one_rom(rom); // audit a disk else if (ROMREGION_ISDISKDATA(region)) record = audit_one_disk(rom); if (record != nullptr) { // count the number of files that are found. if (record->status() == audit_record::STATUS_GOOD || (record->status() == audit_record::STATUS_FOUND_INVALID && find_shared_device(*device, name, record->actual_hashes(), record->actual_length()) == nullptr)) { found++; if (shared_device != nullptr) shared_found++; } record->set_shared_device(shared_device); } } } } // if we only find files that are in the parent & either the set has no unique files or the parent is not found, then assume we don't have the set at all if (found == shared_found && required > 0 && (required != shared_required || shared_found == 0)) { m_record_list.reset(); return NOTFOUND; } // return a summary return summarize(m_enumerator.driver().name); }
//------------------------------------------------- // audit_software //------------------------------------------------- media_auditor::summary media_auditor::audit_software(const char *list_name, software_info *swinfo, const char *validation) { // start fresh m_record_list.reset(); // store validation for later m_validation = validation; std::string combinedpath(swinfo->shortname()); combinedpath.append(";"); combinedpath.append(list_name); combinedpath.append(PATH_SEPARATOR); combinedpath.append(swinfo->shortname()); std::string locationtag(list_name); locationtag.append("%"); locationtag.append(swinfo->shortname()); locationtag.append("%"); if (swinfo->parentname() != nullptr) { locationtag.append(swinfo->parentname()); combinedpath.append(";").append(swinfo->parentname()).append(";").append(list_name).append(PATH_SEPARATOR).append(swinfo->parentname()); } m_searchpath = combinedpath.c_str(); int found = 0; int required = 0; // now iterate over software parts for (software_part &part : swinfo->parts()) { // now iterate over regions for ( const rom_entry *region = part.romdata(); region; region = rom_next_region( region ) ) { // now iterate over rom definitions for (const rom_entry *rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { hash_collection hashes(ROM_GETHASHDATA(rom)); // count the number of files with hashes if (!hashes.flag(hash_collection::FLAG_NO_DUMP) && !ROM_ISOPTIONAL(rom)) { required++; } // audit a file audit_record *record = nullptr; if (ROMREGION_ISROMDATA(region)) { record = audit_one_rom(rom); } // audit a disk else if (ROMREGION_ISDISKDATA(region)) { record = audit_one_disk(rom, locationtag.c_str()); } // count the number of files that are found. if (record != nullptr && (record->status() == audit_record::STATUS_GOOD || record->status() == audit_record::STATUS_FOUND_INVALID)) { found++; } } } } if (found == 0 && required > 0) { m_record_list.reset(); return NOTFOUND; } // return a summary return summarize(list_name); }
/*------------------------------------------------- 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; }
int cli_info_listroms(core_options *options, const char *gamename) { int drvindex, count = 0; /* iterate over drivers */ for (drvindex = 0; drivers[drvindex]; drvindex++) if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0) { const rom_entry *region, *rom, *chunk; /* print the header */ if (count > 0) mame_printf_info("\n"); mame_printf_info("This is the list of the ROMs required for driver \"%s\".\n" "Name Size Checksum\n", drivers[drvindex]->name); /* iterate over regions and then ROMs within the region */ for (region = drivers[drvindex]->rom; region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { const char *name = ROM_GETNAME(rom); const char* hash = ROM_GETHASHDATA(rom); char hashbuf[HASH_BUF_SIZE]; int length = -1; /* accumulate the total length of all chunks */ if (ROMREGION_ISROMDATA(region)) { length = 0; for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk)) length += ROM_GETLENGTH(chunk); } /* start with the name */ mame_printf_info("%-12s ", name); /* output the length next */ if (length >= 0) mame_printf_info("%7d", length); else mame_printf_info(" "); /* output the hash data */ if (!hash_data_has_info(hash, HASH_INFO_NO_DUMP)) { if (hash_data_has_info(hash, HASH_INFO_BAD_DUMP)) mame_printf_info(" BAD"); hash_data_print(hash, 0, hashbuf); mame_printf_info(" %s", hashbuf); } else mame_printf_info(" NO GOOD DUMP KNOWN"); /* end with a CR */ mame_printf_info("\n"); } count++; } return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME; }