Exemple #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;
}
Exemple #2
0
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));
		}
}
Exemple #3
0
BOOL DriverIsHarddisk(int driver_index)
{
	const struct RomModule *region;

	const struct GameDriver *gamedrv = drivers[driver_index];

	for (region = rom_first_region(gamedrv); region; region = rom_next_region(region))
		if (ROMREGION_ISDISKDATA(region))
			return TRUE;

	return FALSE;	
}
Exemple #4
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());
}
Exemple #5
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;
}
Exemple #6
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);
}
Exemple #7
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());
			}
		}
}
Exemple #8
0
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];
}
Exemple #9
0
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));
		}
}
Exemple #10
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);
}
Exemple #11
0
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");
		}
	}
}
Exemple #12
0
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();
}
Exemple #13
0
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];
}
Exemple #14
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;

	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);
}
Exemple #15
0
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);
}
Exemple #16
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);
}
/* 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;
}
Exemple #18
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();
}
Exemple #19
0
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);
}
Exemple #20
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);
}
Exemple #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;
}
Exemple #22
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;
}
Exemple #23
0
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];
}