Beispiel #1
0
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;
}
Beispiel #2
0
int cli_info_listcrc(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;

			/* iterate over regions, and then ROMs 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))
				{
					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++;
		}

	/* return an error if none found */
	return (count > 0) ? MAMERR_NONE : MAMERR_NO_SUCH_GAME;
}
Beispiel #3
0
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 );
}
Beispiel #4
0
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;
}
Beispiel #6
0
/* 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;
}
Beispiel #7
0
device_t *media_auditor::find_shared_device(device_t &device, const hash_collection &romhashes, UINT64 romlength)
{
    // doesn't apply to NO_DUMP items
    if (romhashes.flag(hash_collection::FLAG_NO_DUMP))
        return NULL;

    // 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 (hashes == romhashes)
                        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 (hashes == romhashes)
                                highest_device = scandevice;
                        }
        }
    }

    return highest_device;
}
Beispiel #8
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 != 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());
}
Beispiel #9
0
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");
		}
	}
}
Beispiel #10
0
/*-------------------------------------------------
    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);
	}
}
Beispiel #11
0
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 = nullptr;
	if (device.owner() != nullptr)
	{
		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 != nullptr; 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 != nullptr; 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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
				}
}
Beispiel #14
0
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;
}
Beispiel #15
0
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);
				}
}
Beispiel #16
0
const char *info_xml_creator::get_merge_name(const hash_collection &romhashes)
{
	const char *merge_name = NULL;
	// walk the parent chain
	for (int clone_of = m_drivlist.find(m_drivlist.driver().parent); clone_of != -1; clone_of = m_drivlist.find(m_drivlist.driver(clone_of).parent))

		// look in the parent's ROMs
		for (const rom_source *psource = rom_first_source(m_drivlist.config(clone_of,m_lookup_options)); psource != NULL; psource = rom_next_source(*psource))
			for (const rom_entry *pregion = rom_first_region(*psource); pregion != NULL; pregion = rom_next_region(pregion))
				for (const rom_entry *prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom))
				{
					hash_collection phashes(ROM_GETHASHDATA(prom));
					if (!phashes.flag(hash_collection::FLAG_NO_DUMP) && romhashes == phashes)
					{
						// stop when we find a match
						merge_name = ROM_GETNAME(prom);
						break;
					}
				}

	return merge_name;
}
Beispiel #17
0
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;
}
Beispiel #18
0
/* 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)++;
			}
		}
	}
}
Beispiel #19
0
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)++;
				}
	}
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
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);
}
Beispiel #23
0
//-------------------------------------------------
//  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);
}
Beispiel #24
0
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;
}
Beispiel #25
0
int load_driver_mameinfo(const game_driver *drv, char *buffer, int bufsize, int filenum)
{
	machine_config config(*drv, MameUIGlobal());
	const game_driver *parent = NULL;
	char name[512];
	int mameinfo = 0;
	int is_bios = 0;

	*buffer = 0;

	if (filenum)
		snprintf(filename, ARRAY_LENGTH(filename), "%s\\messinfo.dat", GetDatsDir());
	else
		snprintf(filename, ARRAY_LENGTH(filename), "%s\\mameinfo.dat", GetDatsDir());

	if (filenum)
		strcat(buffer, "\n**** MESSINFO: ****\n\n");
	else
		strcat(buffer, "\n**** MAMEINFO: ****\n\n");

	/* List the game info 'flags' */
	if (drv->flags & MACHINE_NOT_WORKING)
		strcat(buffer, "THIS GAME DOESN'T WORK PROPERLY\n");

	if (drv->flags & MACHINE_UNEMULATED_PROTECTION)
		strcat(buffer, "The game has protection which isn't fully emulated.\n");

	if (drv->flags & MACHINE_IMPERFECT_GRAPHICS)
		strcat(buffer, "The video emulation isn't 100% accurate.\n");

	if (drv->flags & MACHINE_WRONG_COLORS)
		strcat(buffer, "The colors are completely wrong.\n");

	if (drv->flags & MACHINE_IMPERFECT_COLORS)
		strcat(buffer, "The colors aren't 100% accurate.\n");

	if (drv->flags & MACHINE_NO_SOUND)
		strcat(buffer, "The game lacks sound.\n");

	if (drv->flags & MACHINE_IMPERFECT_SOUND)
		strcat(buffer, "The sound emulation isn't 100% accurate.\n");

	if (drv->flags & MACHINE_SUPPORTS_SAVE)
		strcat(buffer, "Save state support.\n");

	if (drv->flags & MACHINE_MECHANICAL)
		strcat(buffer, "The game contains mechanical parts.\n");

	strcat(buffer, "\n");

	if (drv->flags & MACHINE_IS_BIOS_ROOT)
		is_bios = 1;

	/* try to open mameinfo datafile */
	if (ParseOpen(filename))
	{
		if (filenum)
		{
			/* create index if necessary */
			if (mess_idx)
				mameinfo = 1;
			else
				mameinfo = (index_datafile (&mess_idx, 0) != 0);

			/* load informational text (append) */
			if (mess_idx)
			{
				int len = strlen(buffer);
				int err = 0;
				const game_driver *gdrv;
				gdrv = drv;

				do
				{
					err = load_datafile_text(gdrv, buffer + len, bufsize - len, mess_idx, DATAFILE_TAG_MAME, 0, 1);
					int g = driver_list::clone(*gdrv);

					if (g!=-1)
						gdrv = &driver_list::driver(g);
					else
						gdrv = NULL;
				} while (err && gdrv);

				if (err)
					mameinfo = 0;
			}
		}
		else
		{
			/* create index if necessary */
			if (mame_idx)
				mameinfo = 1;
			else
				mameinfo = (index_datafile (&mame_idx, 0) != 0);

			/* load informational text (append) */
			if (mame_idx)
			{
				int len = strlen(buffer);
				int err = 0;
				const game_driver *gdrv;
				gdrv = drv;

				do
				{
					err = load_datafile_text(gdrv, buffer + len, bufsize - len, mame_idx, DATAFILE_TAG_MAME, 0, 1);
					int g = driver_list::clone(*gdrv);

					if (g!=-1)
						gdrv = &driver_list::driver(g);
					else
						gdrv = NULL;
				} while (err && gdrv);

				if (err)
					mameinfo = 0;
			}
		}

		ParseClose();
	}

	/* GAME INFORMATIONS */
	snprintf(name, ARRAY_LENGTH(name), "\nGAME: %s\n", drv->name);
	strcat(buffer, name);
	snprintf(name, ARRAY_LENGTH(name), "%s", drv->description);
	strcat(buffer, name);
	snprintf(name, ARRAY_LENGTH(name), " (%s %s)\n\nCPU:\n", drv->manufacturer, drv->year);
	strcat(buffer, name);
	/* iterate over CPUs */
	execute_interface_iterator iter(config.root_device());
	device_execute_interface *cpu = iter.first();

	while (cpu)
	{
		if (cpu->device().clock() >= 1000000)
			snprintf(name, ARRAY_LENGTH(name), "%s %d.%06d MHz\n", cpu->device().name(), cpu->device().clock() / 1000000, cpu->device().clock() % 1000000);
		else
			snprintf(name, ARRAY_LENGTH(name), "%s %d.%03d kHz\n", cpu->device().name(), cpu->device().clock() / 1000, cpu->device().clock() % 1000);

		strcat(buffer, name);
		cpu = iter.next();
	}

	strcat(buffer, "\nSOUND:\n");
	int has_sound = 0;
	/* iterate over sound chips */
	sound_interface_iterator sounditer(config.root_device());
	const device_sound_interface *sound = sounditer.first();

	while(sound)
	{
		int clock = 0;
		int count = 0;
		device_type sound_type_;
		char tmpname[1024];

		snprintf(tmpname, ARRAY_LENGTH(tmpname), "%s", sound->device().name());
		sound_type_ = sound->device().type();
		clock = sound->device().clock();
		has_sound = 1;
		count = 1;
		sound = sounditer.next();

		/* Matching chips at the same clock are aggregated */
		while (sound && sound->device().type() == sound_type_ && sound->device().clock() == clock)
		{
			count++;
			sound = sounditer.next();
		}

		if (count > 1)
		{
			snprintf(name, ARRAY_LENGTH(name), "%dx ",count);
			strcat(buffer, name);
		}

		strcat(buffer, tmpname);

		if (clock)
		{
			if (clock >= 1000000)
				snprintf(name, ARRAY_LENGTH(name), " %d.%06d MHz", clock / 1000000, clock % 1000000);
			else
				snprintf(name, ARRAY_LENGTH(name), " %d.%03d kHz", clock / 1000, clock % 1000);

			strcat(buffer, name);
		}

		strcat(buffer, "\n");
	}

	if (has_sound)
	{
		speaker_device_iterator iter(config.root_device());
		int channels = iter.count();

		if(channels == 1)
			snprintf(name, ARRAY_LENGTH(name), "%d Channel\n",channels);
		else
			snprintf(name, ARRAY_LENGTH(name), "%dx Channels\n",channels);

		strcat(buffer, name);
	}

	strcat(buffer, "\nVIDEO:\n");
	screen_device_iterator screeniter(config.root_device());
	const screen_device *screen = screeniter.first();

	if (screen == nullptr)
		strcat(buffer, "Screenless\n");
	else if (screen->screen_type() == SCREEN_TYPE_VECTOR)
		strcat(buffer,"Vector\n");
	else
	{
		for (; screen != nullptr; screen = screeniter.next())
		{
			if (drv->flags & ORIENTATION_SWAP_XY)
				snprintf(name, ARRAY_LENGTH(name), "%d x %d (V)", screen->visible_area().height(), screen->visible_area().width());
			else
				snprintf(name, ARRAY_LENGTH(name), "%d x %d (H)", screen->visible_area().width(), screen->visible_area().height());

			strcat(buffer, name);
			snprintf(name, ARRAY_LENGTH(name), " %f Hz", ATTOSECONDS_TO_HZ(screen->refresh_attoseconds()));
			strcat(buffer, name);
			strcat(buffer, "\n");
		}
	}

	strcat(buffer, "\nROM REGION:\n");
	int g = driver_list::clone(*drv);

	if (g!=-1)
		parent = &driver_list::driver(g);

	device_iterator deviter(config.root_device());

	for (device_t *device = deviter.first(); device; device = deviter.next())
	{
		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 != nullptr; rom = rom_next_file(rom))
			{
				hash_collection hashes(ROM_GETHASHDATA(rom));

				if (g!=-1)
				{
					machine_config pconfig(*parent, MameUIGlobal());
					device_iterator deviter(pconfig.root_device());

					for (device_t *device = deviter.first(); device != nullptr; device = deviter.next())
						for (const rom_entry *pregion = rom_first_region(*device); pregion != nullptr; pregion = rom_next_region(pregion))
							for (const rom_entry *prom = rom_first_file(pregion); prom != nullptr; prom = rom_next_file(prom))
							{
								hash_collection phashes(ROM_GETHASHDATA(prom));

								if (hashes == phashes)
									break;
							}
				}

				snprintf(name, ARRAY_LENGTH(name), "%-16s \t", ROM_GETNAME(rom));
				strcat(buffer, name);
				snprintf(name, ARRAY_LENGTH(name), "%09d \t", rom_file_size(rom));
				strcat(buffer, name);
				snprintf(name, ARRAY_LENGTH(name), "%-10s", ROMREGION_GETTAG(region));
				strcat(buffer, name);
				strcat(buffer, "\n");
			}
		}
	}

	samples_device_iterator samplesiter(config.root_device());

	for (samples_device *device = samplesiter.first(); device != nullptr; device = samplesiter.next())
	{
		samples_iterator sampiter(*device);

		if (sampiter.altbasename() != nullptr)
		{
			snprintf(name, ARRAY_LENGTH(name), "\nSAMPLES (%s):\n", sampiter.altbasename());
			strcat(buffer, name);
		}

		std::unordered_set<std::string> already_printed;

		for (const char *samplename = sampiter.first(); samplename != nullptr; samplename = sampiter.next())
		{
			// filter out duplicates
			if (!already_printed.insert(samplename).second)
				continue;

			// output the sample name
			snprintf(name, ARRAY_LENGTH(name), "%s.wav\n", samplename);
			strcat(buffer, name);
		}
	}

	if (!is_bios)
	{
		int g = driver_list::clone(*drv);

		if (g!=-1)
			drv = &driver_list::driver(g);

		strcat(buffer, "\nORIGINAL:\n");
		strcat(buffer, drv->description);
		strcat(buffer, "\n\nCLONES:\n");

		for (int i = 0; i < driver_list::total(); i++)
		{
			if (!strcmp (drv->name, driver_list::driver(i).parent))
			{
				strcat(buffer, driver_list::driver(i).description);
				strcat(buffer, "\n");
			}
		}
	}

	strcat(buffer, "\n");
	return (mameinfo == 0);
}
Beispiel #26
0
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();
}
Beispiel #27
0
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);
}
Beispiel #28
0
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());
			}
		}
}
Beispiel #29
0
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;
}
Beispiel #30
0
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);
}