int audit_images(int game, UINT32 validation, audit_record **audit) { const game_driver *gamedrv = drivers[game]; const rom_entry *region, *rom; audit_record *record; int foundany = FALSE; int allshared = TRUE; int records; /* determine the number of records we will generate */ records = 0; for (region = rom_first_region(gamedrv); region != NULL; region = rom_next_region(region)) for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) if (ROMREGION_ISROMDATA(region) || ROMREGION_ISDISKDATA(region)) { if (allshared && !rom_used_by_parent(gamedrv, rom, NULL)) allshared = FALSE; records++; } if (records > 0) { /* allocate memory for the records */ *audit = malloc_or_die(sizeof(**audit) * records); memset(*audit, 0, sizeof(**audit) * records); record = *audit; /* iterate over regions and ROMs */ for (region = rom_first_region(drivers[game]); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { int shared = rom_used_by_parent(gamedrv, rom, NULL); /* audit a file */ if (ROMREGION_ISROMDATA(region)) { if (audit_one_rom(rom, gamedrv, validation, record++) && (!shared || allshared)) foundany = TRUE; } /* audit a disk */ else if (ROMREGION_ISDISKDATA(region)) { if (audit_one_disk(rom, gamedrv, validation, record++) && (!shared || allshared)) foundany = TRUE; } } /* if we found nothing, we don't have the set at all */ if (!foundany) { free(*audit); *audit = NULL; records = 0; } } return records; }
static void process_region_list(romload_private *romdata) { astring regiontag; /* loop until we hit the end */ device_iterator deviter(romdata->machine().root_device()); for (device_t *device = deviter.first(); device != NULL; device = deviter.next()) for (const rom_entry *region = rom_first_region(*device); region != NULL; region = rom_next_region(region)) { UINT32 regionlength = ROMREGION_GETLENGTH(region); rom_region_name(regiontag, *device, region); LOG(("Processing region \"%s\" (length=%X)\n", regiontag.cstr(), 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 (romdata->machine().device(regiontag) != NULL) normalize_flags_for_device(romdata->machine(), regiontag, width, endianness); /* 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 /* now process the entries in the region */ process_rom_entries(romdata, device->shortname(), region, region + 1, device, FALSE); } else if (ROMREGION_ISDISKDATA(region)) process_disk_entries(romdata, regiontag, region, region + 1, NULL); } /* now go back and post-process all the regions */ for (device_t *device = deviter.first(); device != NULL; device = deviter.next()) for (const rom_entry *region = rom_first_region(*device); region != NULL; region = rom_next_region(region)) { rom_region_name(regiontag, *device, region); region_post_process(romdata, regiontag, ROMREGION_ISINVERTED(region)); } }
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; }
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 != nullptr; 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 = nullptr; 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 != 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(device->shortname()); }
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; }
static void print_game_rom(FILE *out, const game_driver *game, const machine_config *config) { const game_driver *clone_of = driver_get_clone(game); int rom_type; machine_config *pconfig = (clone_of != NULL) ? machine_config_alloc(clone_of->machine_config) : NULL; /* iterate over 3 different ROM "types": BIOS, ROMs, DISKs */ for (rom_type = 0; rom_type < 3; rom_type++) { const rom_source *source; const rom_entry *region; /* iterate over ROM sources: first the game, then any devices */ for (source = rom_first_source(game, config); source != NULL; source = rom_next_source(game, config, source)) for (region = rom_first_region(game, source); region != NULL; region = rom_next_region(region)) { int is_disk = ROMREGION_ISDISKDATA(region); const rom_entry *rom; /* disk regions only work for disks */ if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2)) continue; /* iterate through ROM entries */ for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) { int is_bios = ROM_GETBIOSFLAGS(rom); const char *name = ROM_GETNAME(rom); int offset = ROM_GETOFFSET(rom); const rom_entry *parent_rom = NULL; char bios_name[100]; /* BIOS ROMs only apply to bioses */ if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0)) continue; /* if we have a valid ROM and we are a clone, see if we can find the parent ROM */ if (!ROM_NOGOODDUMP(rom) && clone_of != NULL) { const rom_source *psource; const rom_entry *pregion, *prom; /* scan the clone_of ROM for a matching ROM entry */ for (psource = rom_first_source(clone_of, pconfig); psource != NULL; psource = rom_next_source(clone_of, pconfig, psource)) for (pregion = rom_first_region(clone_of, psource); pregion != NULL; pregion = rom_next_region(pregion)) for (prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom)) if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0)) { parent_rom = prom; break; } } /* scan for a BIOS name */ bios_name[0] = 0; if (!is_disk && is_bios) { const rom_entry *brom; /* scan backwards through the ROM entries */ for (brom = rom - 1; brom != game->rom; brom--) if (ROMENTRY_ISSYSTEM_BIOS(brom)) { strcpy(bios_name, ROM_GETNAME(brom)); break; } } /* opening tag */ if (!is_disk) fprintf(out, "\t\t<rom"); else fprintf(out, "\t\t<disk"); /* add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) fprintf(out, " name=\"%s\"", xml_normalize_string(name)); if (parent_rom != NULL) fprintf(out, " merge=\"%s\"", xml_normalize_string(ROM_GETNAME(parent_rom))); if (bios_name[0] != 0) fprintf(out, " bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) fprintf(out, " size=\"%d\"", 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); } /* append a region name */ fprintf(out, " region=\"%s\"", ROMREGION_GETTAG(region)); /* add nodump/baddump flags */ if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) fprintf(out, " status=\"nodump\""); if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP)) fprintf(out, " status=\"baddump\""); /* for non-disk entries, print offset */ if (!is_disk) fprintf(out, " offset=\"%x\"", offset); /* for disk entries, add the disk index */ else fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom)); /* add optional flag */ if ((!is_disk && ROM_ISOPTIONAL(rom)) || (is_disk && DISK_ISOPTIONAL(rom))) fprintf(out, " optional=\"yes\""); fprintf(out, "/>\n"); } } } if (pconfig != NULL) machine_config_free(pconfig); }
void info_xml_creator::output_rom(device_t &device) { // iterate over 3 different ROM "types": BIOS, ROMs, DISKs for (int rom_type = 0; rom_type < 3; rom_type++) for (const rom_entry *region = rom_first_region(device); region != NULL; region = rom_next_region(region)) { bool is_disk = ROMREGION_ISDISKDATA(region); // disk regions only work for disks if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2)) continue; // iterate through ROM entries for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) { bool is_bios = ROM_GETBIOSFLAGS(rom); const char *name = ROM_GETNAME(rom); int offset = ROM_GETOFFSET(rom); const char *merge_name = NULL; char bios_name[100]; // BIOS ROMs only apply to bioses if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0)) continue; // if we have a valid ROM and we are a clone, see if we can find the parent ROM hash_collection hashes(ROM_GETHASHDATA(rom)); if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) merge_name = get_merge_name(hashes); if (&device != &m_drivlist.config().root_device()) merge_name = NULL; // scan for a BIOS name bios_name[0] = 0; if (!is_disk && is_bios) { // scan backwards through the ROM entries for (const rom_entry *brom = rom - 1; brom != m_drivlist.driver().rom; brom--) if (ROMENTRY_ISSYSTEM_BIOS(brom)) { strcpy(bios_name, ROM_GETNAME(brom)); break; } } astring output; // opening tag if (!is_disk) output.cat("\t\t<rom"); else output.cat("\t\t<disk"); // add name, merge, bios, and size tags */ if (name != NULL && name[0] != 0) output.catprintf(" name=\"%s\"", xml_normalize_string(name)); if (merge_name != NULL) output.catprintf(" merge=\"%s\"", xml_normalize_string(merge_name)); if (bios_name[0] != 0) output.catprintf(" bios=\"%s\"", xml_normalize_string(bios_name)); if (!is_disk) output.catprintf(" size=\"%d\"", rom_file_size(rom)); // dump checksum information only if there is a known dump if (!hashes.flag(hash_collection::FLAG_NO_DUMP)) { // iterate over hash function types and print m_output their values astring tempstr; output.catprintf(" %s", hashes.attribute_string(tempstr)); } else output.cat(" status=\"nodump\""); // append a region name output.catprintf(" region=\"%s\"", ROMREGION_GETTAG(region)); // for non-disk entries, print offset if (!is_disk) output.catprintf(" offset=\"%x\"", offset); // for disk entries, add the disk index else { output.catprintf(" index=\"%x\"", DISK_GETINDEX(rom)); output.catprintf(" writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes"); } // add optional flag if (ROM_ISOPTIONAL(rom)) output.cat(" optional=\"yes\""); output.cat("/>\n"); fprintf(m_output, "%s", output.cstr()); } } }
static struct DriversInfo* GetDriversInfo(int driver_index) { if (drivers_info == NULL) { int ndriver; drivers_info = (DriversInfo*)malloc(sizeof(struct DriversInfo) * GetNumGames()); for (ndriver = 0; ndriver < GetNumGames(); ndriver++) { const game_driver *gamedrv = drivers[ndriver]; struct DriversInfo *gameinfo = &drivers_info[ndriver]; const rom_entry *region, *rom; machine_config *config; const rom_source *source; int num_speakers; /* Allocate machine config */ config = global_alloc(machine_config(gamedrv->machine_config)); gameinfo->isClone = (GetParentRomSetIndex(gamedrv) != -1); gameinfo->isBroken = ((gamedrv->flags & GAME_NOT_WORKING) != 0); gameinfo->supportsSaveState = ((gamedrv->flags & GAME_SUPPORTS_SAVE) != 0); gameinfo->isHarddisk = FALSE; gameinfo->isVertical = (gamedrv->flags & ORIENTATION_SWAP_XY) ? TRUE : FALSE; for (source = rom_first_source(gamedrv, config); source != NULL; source = rom_next_source(gamedrv, config, source)) { for (region = rom_first_region(gamedrv, source); region; region = rom_next_region(region)) { if (ROMREGION_ISDISKDATA(region)) gameinfo->isHarddisk = TRUE; } } gameinfo->hasOptionalBIOS = FALSE; if (gamedrv->rom != NULL) { for (rom = gamedrv->rom; !ROMENTRY_ISEND(rom); rom++) { if (ROMENTRY_ISSYSTEM_BIOS(rom)) { gameinfo->hasOptionalBIOS = TRUE; break; } } } num_speakers = numberOfSpeakers(config); gameinfo->isStereo = (num_speakers > 1); gameinfo->screenCount = numberOfScreens(config); gameinfo->isVector = isDriverVector(config); // ((drv.video_attributes & VIDEO_TYPE_VECTOR) != 0); gameinfo->usesRoms = FALSE; for (source = rom_first_source(gamedrv, config); source != NULL; source = rom_next_source(gamedrv, config, source)) { for (region = rom_first_region(gamedrv, source); region; region = rom_next_region(region)) { for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { gameinfo->usesRoms = TRUE; break; } } } gameinfo->usesSamples = FALSE; { const device_config_sound_interface *sound; const char * const * samplenames = NULL; for (bool gotone = config->m_devicelist.first(sound); gotone; gotone = sound->next(sound)) { if (sound->devconfig().type() == SOUND_SAMPLES) { const samples_interface *intf = (const samples_interface *)sound->devconfig().static_config(); samplenames = intf->samplenames; if (samplenames != 0 && samplenames[0] != 0) { gameinfo->usesSamples = TRUE; break; } } } } gameinfo->numPlayers = 0; gameinfo->numButtons = 0; memset(gameinfo->usesController, 0, sizeof gameinfo->usesController); gameinfo->parentIndex = -1; if (gameinfo->isClone) { int i; for (i = 0; i < GetNumGames(); i++) { if (GetParentRomSetIndex(gamedrv) == i) { gameinfo->parentIndex = i; break; } } } gameinfo->biosIndex = -1; if (DriverIsBios(ndriver)) gameinfo->biosIndex = ndriver; else if (gameinfo->hasOptionalBIOS) { int parentIndex; if (gameinfo->isClone) parentIndex = gameinfo->parentIndex; else parentIndex = ndriver; while (1) { parentIndex = GetGameNameIndex(drivers[parentIndex]->parent); if (parentIndex == -1) { dprintf("bios for %s is not found", drivers[ndriver]->name); break; } if (DriverIsBios(parentIndex)) { gameinfo->biosIndex = parentIndex; break; } } } /* Free the structure */ global_free(config); gameinfo->usesTrackball = FALSE; gameinfo->usesLightGun = FALSE; if (gamedrv->ipt != NULL) { const input_port_config *port; ioport_list portlist; input_port_list_init(portlist, gamedrv->ipt, NULL, 0, FALSE); for (port = portlist.first(); port != NULL; port = port->next()) { const input_field_config *field; for (field = port->fieldlist; field != NULL; field = field->next) { UINT32 type; type = field->type; if (type == IPT_END) break; if (type == IPT_DIAL || type == IPT_PADDLE || type == IPT_TRACKBALL_X || type == IPT_TRACKBALL_Y || type == IPT_AD_STICK_X || type == IPT_AD_STICK_Y) gameinfo->usesTrackball = TRUE; if (type == IPT_LIGHTGUN_X || type == IPT_LIGHTGUN_Y) gameinfo->usesLightGun = TRUE; if (type == IPT_MOUSE_X || type == IPT_MOUSE_Y) gameinfo->usesMouse = TRUE; } } } } UpdateController(); } return &drivers_info[driver_index]; }
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().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); }
static void print_game_rom(FILE* out, const game_driver* game) { const rom_entry *region, *rom, *chunk; const rom_entry *pregion, *prom, *fprom=NULL; const game_driver *clone_of; if (!game->rom) return; clone_of = driver_get_clone(game); for (region = rom_first_region(game); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { int offset, length, in_parent, is_disk, is_bios, found_bios, i; char name[100], bios_name[100]; strcpy(name,ROM_GETNAME(rom)); offset = ROM_GETOFFSET(rom); is_disk = ROMREGION_ISDISKDATA(region); is_bios = ROM_GETBIOSFLAGS(rom); in_parent = 0; length = 0; for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk)) length += ROM_GETLENGTH(chunk); if (!ROM_NOGOODDUMP(rom) && clone_of) { fprom=NULL; for (pregion = rom_first_region(clone_of); pregion; pregion = rom_next_region(pregion)) for (prom = rom_first_file(pregion); prom; prom = rom_next_file(prom)) if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0)) { if (!fprom || !strcmp(ROM_GETNAME(prom), name)) fprom=prom; in_parent = 1; } } found_bios = 0; if(!is_disk && is_bios && game->bios) { const bios_entry *thisbios = game->bios; /* Match against bios short names */ while(!found_bios && !BIOSENTRY_ISEND(thisbios) ) { if((is_bios-1) == thisbios->value) /* Note '-1' */ { strcpy(bios_name,thisbios->_name); found_bios = 1; } thisbios++; } } if (!is_disk) fprintf(out, "\t\t<rom"); else fprintf(out, "\t\t<disk"); if (*name) fprintf(out, " name=\"%s\"", normalize_string(name)); if (in_parent) fprintf(out, " merge=\"%s\"", normalize_string(ROM_GETNAME(fprom))); if (!is_disk && found_bios) fprintf(out, " bios=\"%s\"", normalize_string(bios_name)); if (!is_disk) fprintf(out, " size=\"%d\"", length); /* dump checksum information only if there is a known dump */ if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) { for (i=0;i<HASH_NUM_FUNCTIONS;i++) { int func = 1<<i; const char* func_name = hash_function_name(func); char checksum[1000]; if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), func, checksum)) { fprintf(out, " %s=\"%s\"", func_name, checksum); } } } switch (ROMREGION_GETTYPE(region)) { case REGION_CPU1: fprintf(out, " region=\"cpu1\""); break; case REGION_CPU2: fprintf(out, " region=\"cpu2\""); break; case REGION_CPU3: fprintf(out, " region=\"cpu3\""); break; case REGION_CPU4: fprintf(out, " region=\"cpu4\""); break; case REGION_CPU5: fprintf(out, " region=\"cpu5\""); break; case REGION_CPU6: fprintf(out, " region=\"cpu6\""); break; case REGION_CPU7: fprintf(out, " region=\"cpu7\""); break; case REGION_CPU8: fprintf(out, " region=\"cpu8\""); break; case REGION_GFX1: fprintf(out, " region=\"gfx1\""); break; case REGION_GFX2: fprintf(out, " region=\"gfx2\""); break; case REGION_GFX3: fprintf(out, " region=\"gfx3\""); break; case REGION_GFX4: fprintf(out, " region=\"gfx4\""); break; case REGION_GFX5: fprintf(out, " region=\"gfx5\""); break; case REGION_GFX6: fprintf(out, " region=\"gfx6\""); break; case REGION_GFX7: fprintf(out, " region=\"gfx7\""); break; case REGION_GFX8: fprintf(out, " region=\"gfx8\""); break; case REGION_PROMS: fprintf(out, " region=\"proms\""); break; case REGION_SOUND1: fprintf(out, " region=\"sound1\""); break; case REGION_SOUND2: fprintf(out, " region=\"sound2\""); break; case REGION_SOUND3: fprintf(out, " region=\"sound3\""); break; case REGION_SOUND4: fprintf(out, " region=\"sound4\""); break; case REGION_SOUND5: fprintf(out, " region=\"sound5\""); break; case REGION_SOUND6: fprintf(out, " region=\"sound6\""); break; case REGION_SOUND7: fprintf(out, " region=\"sound7\""); break; case REGION_SOUND8: fprintf(out, " region=\"sound8\""); break; case REGION_USER1: fprintf(out, " region=\"user1\""); break; case REGION_USER2: fprintf(out, " region=\"user2\""); break; case REGION_USER3: fprintf(out, " region=\"user3\""); break; case REGION_USER4: fprintf(out, " region=\"user4\""); break; case REGION_USER5: fprintf(out, " region=\"user5\""); break; case REGION_USER6: fprintf(out, " region=\"user6\""); break; case REGION_USER7: fprintf(out, " region=\"user7\""); break; case REGION_USER8: fprintf(out, " region=\"user8\""); break; case REGION_DISKS: fprintf(out, " region=\"disks\""); break; default: fprintf(out, " region=\"0x%x\"", ROMREGION_GETTYPE(region)); } if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) fprintf(out, " status=\"nodump\""); if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP)) fprintf(out, " status=\"baddump\""); if (!is_disk) { if (ROMREGION_GETFLAGS(region) & ROMREGION_DISPOSE) fprintf(out, " dispose=\"yes\""); fprintf(out, " offset=\"%x\"", offset); fprintf(out, "/>\n"); } else { fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom)); fprintf(out, "/>\n"); } } }
static void InitDriversInfo(void) { int ndriver; int num_speakers = 0; int total = driver_list::total(); const game_driver *gamedrv = NULL; struct DriversInfo *gameinfo = NULL; const rom_entry *region, *rom; for (ndriver = 0; ndriver < total; ndriver++) { gamedrv = &driver_list::driver(ndriver); gameinfo = &drivers_info[ndriver]; machine_config config(*gamedrv, MameUIGlobal()); gameinfo->isClone = (GetParentRomSetIndex(gamedrv) != -1); gameinfo->isBroken = (gamedrv->flags & MACHINE_NOT_WORKING) ? true : false; gameinfo->isHarddisk = FALSE; gameinfo->isVertical = (gamedrv->flags & ORIENTATION_SWAP_XY) ? TRUE : FALSE; device_iterator deviter(config.root_device()); for (device_t *device = deviter.first(); device; device = deviter.next()) for (region = rom_first_region(*device); region; region = rom_next_region(region)) if (ROMREGION_ISDISKDATA(region)) gameinfo->isHarddisk = TRUE; gameinfo->hasOptionalBIOS = FALSE; if (gamedrv->rom) for (rom = gamedrv->rom; !ROMENTRY_ISEND(rom); rom++) if (ROMENTRY_ISSYSTEM_BIOS(rom)) gameinfo->hasOptionalBIOS = TRUE; num_speakers = numberOfSpeakers(&config); gameinfo->isStereo = (num_speakers > 1); gameinfo->screenCount = numberOfScreens(&config); gameinfo->isVector = isDriverVector(&config); gameinfo->usesRoms = FALSE; for (device_t *device = deviter.first(); device; device = deviter.next()) for (region = rom_first_region(*device); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) gameinfo->usesRoms = TRUE; gameinfo->usesSamples = FALSE; samples_device_iterator iter(config.root_device()); if (iter.first()) gameinfo->usesSamples = TRUE; gameinfo->usesTrackball = FALSE; gameinfo->usesLightGun = FALSE; if (gamedrv->ipt) { ioport_port *port; ioport_list portlist; std::string errors; device_iterator iter(config.root_device()); for (device_t *cfg = iter.first(); cfg; cfg = iter.next()) if (cfg->input_ports()) portlist.append(*cfg, errors); for (port = portlist.first(); port; port = port->next()) { ioport_field *field; for (field = port->first_field(); field; field = field->next()) { UINT32 type; type = field->type(); if (type == IPT_END) break; if (type == IPT_DIAL || type == IPT_PADDLE || type == IPT_TRACKBALL_X || type == IPT_TRACKBALL_Y || type == IPT_AD_STICK_X || type == IPT_AD_STICK_Y) gameinfo->usesTrackball = TRUE; if (type == IPT_LIGHTGUN_X || type == IPT_LIGHTGUN_Y) gameinfo->usesLightGun = TRUE; if (type == IPT_MOUSE_X || type == IPT_MOUSE_Y) gameinfo->usesMouse = TRUE; } } } } SetDriversInfo(); }
static struct DriversInfo* GetDriversInfo(int driver_index) { if (drivers_info == NULL) { int ndriver; drivers_info = (DriversInfo*)malloc(sizeof(struct DriversInfo) * driver_list_get_count(drivers)); for (ndriver = 0; ndriver < driver_list_get_count(drivers); ndriver++) { const game_driver *gamedrv = drivers[ndriver]; struct DriversInfo *gameinfo = &drivers_info[ndriver]; const rom_entry *region, *rom; windows_options pCurrentOpts; load_options(pCurrentOpts, OPTIONS_GLOBAL, driver_index); machine_config config(*gamedrv,pCurrentOpts); const rom_source *source; int num_speakers; gameinfo->isClone = (GetParentRomSetIndex(gamedrv) != -1); gameinfo->isBroken = ((gamedrv->flags & GAME_NOT_WORKING) != 0); gameinfo->supportsSaveState = ((gamedrv->flags & GAME_SUPPORTS_SAVE) != 0); gameinfo->isHarddisk = FALSE; gameinfo->isVertical = (gamedrv->flags & ORIENTATION_SWAP_XY) ? TRUE : FALSE; for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) { for (region = rom_first_region(*source); region; region = rom_next_region(region)) { if (ROMREGION_ISDISKDATA(region)) gameinfo->isHarddisk = TRUE; } } gameinfo->hasOptionalBIOS = FALSE; if (gamedrv->rom != NULL) { for (rom = gamedrv->rom; !ROMENTRY_ISEND(rom); rom++) { if (ROMENTRY_ISSYSTEM_BIOS(rom)) { gameinfo->hasOptionalBIOS = TRUE; break; } } } num_speakers = numberOfSpeakers(&config); gameinfo->isStereo = (num_speakers > 1); gameinfo->screenCount = numberOfScreens(&config); gameinfo->isVector = isDriverVector(&config); // ((drv.video_attributes & VIDEO_TYPE_VECTOR) != 0); gameinfo->usesRoms = FALSE; for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) { for (region = rom_first_region(*source); region; region = rom_next_region(region)) { for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { gameinfo->usesRoms = TRUE; break; } } } gameinfo->usesSamples = FALSE; { const device_config_sound_interface *sound = NULL; const char * const * samplenames = NULL; for (bool gotone = config.m_devicelist.first(sound); gotone; gotone = sound->next(sound)) { if (sound->devconfig().type() == SAMPLES) { const samples_interface *intf = (const samples_interface *)sound->devconfig().static_config(); samplenames = intf->samplenames; if (samplenames != 0 && samplenames[0] != 0) { gameinfo->usesSamples = TRUE; break; } } } } gameinfo->usesTrackball = FALSE; gameinfo->usesLightGun = FALSE; if (gamedrv->ipt != NULL) { const input_port_config *port; ioport_list portlist; input_port_list_init(portlist, gamedrv->ipt, NULL, 0, FALSE, NULL); for (device_config *cfg = config.m_devicelist.first(); cfg != NULL; cfg = cfg->next()) { if (cfg->input_ports()!=NULL) { input_port_list_init(portlist, cfg->input_ports(), NULL, 0, FALSE, cfg); } } for (port = portlist.first(); port != NULL; port = port->next()) { const input_field_config *field; for (field = port->fieldlist; field != NULL; field = field->next) { UINT32 type; type = field->type; if (type == IPT_END) break; if (type == IPT_DIAL || type == IPT_PADDLE || type == IPT_TRACKBALL_X || type == IPT_TRACKBALL_Y || type == IPT_AD_STICK_X || type == IPT_AD_STICK_Y) gameinfo->usesTrackball = TRUE; if (type == IPT_LIGHTGUN_X || type == IPT_LIGHTGUN_Y) gameinfo->usesLightGun = TRUE; if (type == IPT_MOUSE_X || type == IPT_MOUSE_Y) gameinfo->usesMouse = TRUE; } } } } } return &drivers_info[driver_index]; }
//------------------------------------------------- // 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; astring combinedpath(swinfo->shortname, ";", list_name, PATH_SEPARATOR, swinfo->shortname); m_searchpath = combinedpath; int found = 0; int required = 0; // now iterate over software parts for ( software_part *part = software_find_part( swinfo, NULL, NULL ); part != NULL; part = software_part_next( part ) ) { // 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 = 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(list_name); }
void rom_init(running_machine *machine, const rom_entry *romp) { const rom_entry *regionlist[REGION_MAX]; const rom_entry *region; static rom_load_data romdata; int regnum; /* if no roms, bail */ if (romp == NULL) return; /* make sure we get called back on the way out */ add_exit_callback(machine, rom_exit); /* reset the region list */ memset((void *)regionlist, 0, sizeof(regionlist)); /* reset the romdata struct */ memset(&romdata, 0, sizeof(romdata)); romdata.romstotal = count_roms(romp); /* reset the disk list */ memset(disk_handle, 0, sizeof(disk_handle)); /* determine the correct biosset to load based on options.bios string */ system_bios = determine_bios_rom(Machine->gamedrv->bios); /* loop until we hit the end */ for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++) { int regiontype = ROMREGION_GETTYPE(region); debugload("Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region)); /* the first entry must be a region */ assert(ROMENTRY_ISREGION(region)); /* remember the base and length */ romdata.regionbase = new_memory_region(machine, regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region)); romdata.regionlength = ROMREGION_GETLENGTH(region); debugload("Allocated %X bytes @ %08X\n", romdata.regionlength, (int)romdata.regionbase); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(romdata.regionbase, ROMREGION_GETERASEVAL(region), romdata.regionlength); /* or if it's sufficiently small (<= 4MB) */ else if (romdata.regionlength <= 0x400000) memset(romdata.regionbase, 0, romdata.regionlength); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(romdata.regionbase, romdata.regionlength); #endif /* now process the entries in the region */ if (ROMREGION_ISROMDATA(region)) process_rom_entries(&romdata, region + 1); else if (ROMREGION_ISDISKDATA(region)) process_disk_entries(&romdata, region + 1); /* add this region to the list */ if (regiontype < REGION_MAX) regionlist[regiontype] = region; } /* post-process the regions */ for (regnum = 0; regnum < REGION_MAX; regnum++) if (regionlist[regnum]) { debugload("Post-processing region %02X\n", regnum); romdata.regionlength = memory_region_length(regnum); romdata.regionbase = memory_region(regnum); region_post_process(&romdata, regionlist[regnum]); } /* display the results and exit */ total_rom_load_warnings = romdata.warnings; display_rom_load_results(&romdata); }
//------------------------------------------------- // 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); }
/* Fills in an audit record for each rom in the romset. Sets 'audit' to point to the list of audit records. Returns total number of roms in the romset (same as number of audit records), 0 if romset missing. */ int audit_roms (int game, audit_record **audit) { const rom_entry *region, *rom, *chunk; const char *name; const game_driver *gamedrv; const game_driver *clone_of; int count = 0; audit_record *aud; int err; if (!audit_records) { audit_records = (audit_record *)malloc (AUD_MAX_ROMS * sizeof (audit_record)); // Make sure the memory is cleared - it's needed by the hashing // engine memset(audit_records, 0, AUD_MAX_ROMS * sizeof(audit_record)); } if (audit_records) *audit = aud = audit_records; else return 0; gamedrv = drivers[game]; clone_of = driver_get_clone(gamedrv); if (!gamedrv->rom) return -1; /* check for existence of romset */ if (!mame_faccess (gamedrv->name, FILETYPE_ROM)) { /* if the game is a clone, check for parent */ if (clone_of == NULL || (clone_of->flags & NOT_A_DRIVER) || !mame_faccess(clone_of->name,FILETYPE_ROM)) return 0; } for (region = rom_first_region(gamedrv); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { if (ROMREGION_ISROMDATA(region)) { const game_driver *drv; name = ROM_GETNAME(rom); strcpy (aud->rom, name); aud->explength = 0; aud->length = 0; aud->exphash = ROM_GETHASHDATA(rom); /* Copy into the variable we pass to the functions to support load-by-checksum */ hash_data_copy(aud->hash, aud->exphash); count++; /* obtain hash checksums and length of ROM file */ drv = gamedrv; do { err = mame_fchecksum(drv->name, name, &aud->length, aud->hash); drv = driver_get_clone(drv); } while (err && drv); /* spin through ROM_CONTINUEs, totaling length */ for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk)) aud->explength += ROM_GETLENGTH(chunk); if (err) { if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) { /* not found but it's not good anyway */ aud->status = AUD_NOT_AVAILABLE; } else if (ROM_ISOPTIONAL(rom)) { /* optional ROM not found */ aud->status = AUD_OPTIONAL_ROM_NOT_FOUND; } else { /* not found */ aud->status = AUD_ROM_NOT_FOUND; drv = clone_of; /* If missing ROM is also present in a parent set, indicate that */ while (drv) { if (audit_is_rom_used (drv, aud->exphash)) { if (drv->flags & NOT_A_DRIVER) { aud->status = AUD_ROM_NOT_FOUND_BIOS; break; } else aud->status = AUD_ROM_NOT_FOUND_PARENT; } // Walk up the inheritance list. If this ROM is a clone of a set which // contains a BIOS that is missing, we can correctly mark it as // such. drv = driver_get_clone(drv); } } } /* all cases below assume the ROM was at least found */ else if (aud->explength != aud->length) aud->status = AUD_LENGTH_MISMATCH; else if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) aud->status = AUD_ROM_NEED_DUMP; /* new case - found but not known to be dumped */ else if (!hash_data_is_equal(aud->exphash, aud->hash, 0)) { /* non-matching hash */ aud->status = AUD_BAD_CHECKSUM; } else { /* matching hash */ if (hash_data_has_info(aud->exphash, HASH_INFO_BAD_DUMP)) aud->status = AUD_ROM_NEED_REDUMP; else aud->status = AUD_ROM_GOOD; } aud++; } else if (ROMREGION_ISDISKDATA(region)) { const UINT8 nullhash[HASH_BUF_SIZE] = { 0 }; void *source; chd_header header; name = ROM_GETNAME(rom); strcpy (aud->rom, name); aud->explength = 0; aud->length = 0; aud->exphash = ROM_GETHASHDATA(rom); hash_data_clear(aud->hash); count++; chd_gamedrv = gamedrv; chd_set_interface(&audit_chd_interface); source = chd_open( name, 0, NULL ); if( source == NULL ) { err = chd_get_last_error(); if( err == CHDERR_OUT_OF_MEMORY ) { aud->status = AUD_MEM_ERROR; } else if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) { /* not found but it's not good anyway */ aud->status = AUD_DISK_NOT_AVAILABLE; } else { /* not found */ aud->status = AUD_DISK_NOT_FOUND; } } else { header = *chd_get_header(source); if (memcmp(nullhash, header.md5, sizeof(header.md5))) hash_data_insert_binary_checksum(aud->hash, HASH_MD5, header.md5); if (memcmp(nullhash, header.sha1, sizeof(header.sha1))) hash_data_insert_binary_checksum(aud->hash, HASH_SHA1, header.sha1); if (hash_data_has_info(aud->exphash, HASH_INFO_NO_DUMP)) { aud->status = AUD_DISK_NEED_DUMP; } else if (!hash_data_is_equal(aud->exphash, aud->hash, 0)) { aud->status = AUD_DISK_BAD_MD5; } else { aud->status = AUD_DISK_GOOD; } chd_close( source ); } aud++; } } #ifdef MESS if (!count) return -1; else #endif return count; }
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(); }
int rom_load(const struct RomModule *romp) { const struct RomModule *regionlist[REGION_MAX]; const struct RomModule *region; static struct rom_load_data romdata; int regnum; /* reset the region list */ for (regnum = 0;regnum < REGION_MAX;regnum++) regionlist[regnum] = NULL; /* reset the romdata struct */ memset(&romdata, 0, sizeof(romdata)); romdata.romstotal = count_roms(romp); /* reset the disk list */ memset(disk_handle, 0, sizeof(disk_handle)); /* determine the correct biosset to load based on options.bios string */ system_bios = determine_bios_rom(Machine->gamedrv->bios); /* loop until we hit the end */ for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++) { int regiontype = ROMREGION_GETTYPE(region); debugload("Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region)); /* the first entry must be a region */ if (!ROMENTRY_ISREGION(region)) { printf("Error: missing ROM_REGION header\n"); return 1; } /* if sound is disabled and it's a sound-only region, skip it */ if (Machine->sample_rate == 0 && ROMREGION_ISSOUNDONLY(region)) continue; /* allocate memory for the region */ if (new_memory_region(regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region))) { printf("Error: unable to allocate memory for region %d\n", regiontype); return 1; } /* remember the base and length */ romdata.regionlength = memory_region_length(regiontype); romdata.regionbase = memory_region(regiontype); debugload("Allocated %X bytes @ %08X\n", romdata.regionlength, (int)romdata.regionbase); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(romdata.regionbase, ROMREGION_GETERASEVAL(region), romdata.regionlength); /* or if it's sufficiently small (<= 4MB) */ else if (romdata.regionlength <= 0x400000) memset(romdata.regionbase, 0, romdata.regionlength); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(romdata.regionbase, romdata.regionlength); #endif /* now process the entries in the region */ if (ROMREGION_ISROMDATA(region)) { if (!process_rom_entries(&romdata, region + 1)) return 1; } else if (ROMREGION_ISDISKDATA(region)) { if (!process_disk_entries(&romdata, region + 1)) return 1; } /* add this region to the list */ if (regiontype < REGION_MAX) regionlist[regiontype] = region; } /* post-process the regions */ for (regnum = 0; regnum < REGION_MAX; regnum++) if (regionlist[regnum]) { debugload("Post-processing region %02X\n", regnum); romdata.regionlength = memory_region_length(regnum); romdata.regionbase = memory_region(regnum); region_post_process(&romdata, regionlist[regnum]); } /* display the results and exit */ return display_rom_load_results(&romdata); }
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); }
int audit_images(core_options *options, const game_driver *gamedrv, UINT32 validation, audit_record **audit) { machine_config *config = global_alloc(machine_config(gamedrv->machine_config)); const rom_entry *region, *rom; const rom_source *source; audit_record *record; int anyfound = FALSE; int anyrequired = FALSE; int allshared = TRUE; int records; /* determine the number of records we will generate */ records = 0; for (source = rom_first_source(gamedrv, config); source != NULL; source = rom_next_source(gamedrv, config, source)) { int source_is_gamedrv = rom_source_is_gamedrv(gamedrv, source); for (region = rom_first_region(gamedrv, source); region != NULL; region = rom_next_region(region)) for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom)) if (ROMREGION_ISROMDATA(region) || ROMREGION_ISDISKDATA(region)) { if (source_is_gamedrv && !ROM_ISOPTIONAL(rom) && !ROM_NOGOODDUMP(rom)) { anyrequired = TRUE; if (allshared && !rom_used_by_parent(gamedrv, rom, NULL)) allshared = FALSE; } records++; } } if (records > 0) { /* allocate memory for the records */ *audit = global_alloc_array_clear(audit_record, records); record = *audit; /* iterate over ROM sources and regions */ for (source = rom_first_source(gamedrv, config); source != NULL; source = rom_next_source(gamedrv, config, source)) { int source_is_gamedrv = rom_source_is_gamedrv(gamedrv, source); for (region = rom_first_region(gamedrv, source); region != NULL; region = rom_next_region(region)) { const char *regiontag = ROMREGION_ISLOADBYNAME(region) ? ROM_GETNAME(region) : NULL; for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { /* audit a file */ if (ROMREGION_ISROMDATA(region)) { audit_one_rom(options, rom, regiontag, gamedrv, validation, record); } /* audit a disk */ else if (ROMREGION_ISDISKDATA(region)) { audit_one_disk(options, rom, gamedrv, validation, record); } else { continue; } if (source_is_gamedrv && record->status != AUDIT_STATUS_NOT_FOUND && (allshared || !rom_used_by_parent(gamedrv, rom, NULL))) anyfound = TRUE; record++; } } } } /* if we found nothing, we don't have the set at all */ if (!anyfound && anyrequired) { global_free(*audit); *audit = NULL; records = 0; } global_free(config); return records; }
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; }
static struct DriversInfo* GetDriversInfo(int driver_index) { if (drivers_info == NULL) { UINT16 ndriver; drivers_info = (DriversInfo*)malloc(sizeof(struct DriversInfo) * GetNumGames()); for (ndriver = 0; ndriver < GetNumGames(); ndriver++) { const game_driver *gamedrv = &driver_list::driver(ndriver); struct DriversInfo *gameinfo = &drivers_info[ndriver]; const rom_entry *region, *rom; machine_config config(*gamedrv, MameUIGlobal()); const rom_source *source; int num_speakers; gameinfo->isClone = (GetParentRomSetIndex(gamedrv) != -1); gameinfo->isBroken = ((gamedrv->flags & GAME_NOT_WORKING) != 0); gameinfo->supportsSaveState = ((gamedrv->flags & GAME_SUPPORTS_SAVE) != 0); gameinfo->isHarddisk = FALSE; gameinfo->isVertical = (gamedrv->flags & ORIENTATION_SWAP_XY) ? TRUE : FALSE; for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) for (region = rom_first_region(*source); region; region = rom_next_region(region)) if (ROMREGION_ISDISKDATA(region)) gameinfo->isHarddisk = TRUE; gameinfo->hasOptionalBIOS = FALSE; if (gamedrv->rom != NULL) for (rom = gamedrv->rom; !ROMENTRY_ISEND(rom); rom++) if (ROMENTRY_ISSYSTEM_BIOS(rom)) { gameinfo->hasOptionalBIOS = TRUE; break; } num_speakers = numberOfSpeakers(&config); gameinfo->isStereo = (num_speakers > 1); gameinfo->screenCount = numberOfScreens(&config); gameinfo->isVector = isDriverVector(&config); // ((drv.video_attributes & VIDEO_TYPE_VECTOR) != 0); gameinfo->usesRoms = FALSE; for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source)) for (region = rom_first_region(*source); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { gameinfo->usesRoms = TRUE; break; } gameinfo->usesSamples = FALSE; samples_device_iterator iter(config.root_device()); if (iter.first() != NULL) gameinfo->usesSamples = TRUE; gameinfo->numPlayers = 0; gameinfo->numButtons = 0; memset(gameinfo->usesController, 0, sizeof gameinfo->usesController); gameinfo->parentIndex = -1; if (gameinfo->isClone) { int i; for (i = 0; i < GetNumGames(); i++) { if (GetParentRomSetIndex(gamedrv) == i) { gameinfo->parentIndex = i; break; } } } gameinfo->biosIndex = -1; if (DriverIsBios(ndriver)) gameinfo->biosIndex = ndriver; else if (gameinfo->hasOptionalBIOS) { int parentIndex; if (gameinfo->isClone) parentIndex = gameinfo->parentIndex; else parentIndex = ndriver; while (1) { parentIndex = GetGameNameIndex(driver_list::driver(parentIndex).parent); if (parentIndex == -1) { dprintf("bios for %s is not found", driver_list::driver(ndriver).name); break; } if (DriverIsBios(parentIndex)) { gameinfo->biosIndex = parentIndex; break; } } } gameinfo->usesTrackball = FALSE; gameinfo->usesLightGun = FALSE; if (gamedrv->ipt != NULL) { input_port_config *port; ioport_list portlist; astring errors; device_iterator iter(config.root_device()); for (device_t *device = iter.first(); device != NULL; device = iter.next()) if (device->input_ports()!=NULL) input_port_list_init(*device, portlist, errors); for (port = portlist.first(); port != NULL; port = port->next()) { const input_field_config *field; for (field = port->first_field(); field != NULL; field = field->next()) { UINT32 type; type = field->type; if (type == IPT_END) break; if (type == IPT_DIAL || type == IPT_PADDLE || type == IPT_TRACKBALL_X || type == IPT_TRACKBALL_Y || type == IPT_AD_STICK_X || type == IPT_AD_STICK_Y) gameinfo->usesTrackball = TRUE; if (type == IPT_LIGHTGUN_X || type == IPT_LIGHTGUN_Y) gameinfo->usesLightGun = TRUE; if (type == IPT_MOUSE_X || type == IPT_MOUSE_Y) gameinfo->usesMouse = TRUE; } } } } UpdateController(); } return &drivers_info[driver_index]; }