Пример #1
0
bool device_image_interface::load_software_part(const char *path, software_part *&swpart)
{
	// if no match has been found, we suggest similar shortnames
	swpart = find_software_item(path, true);
	if (swpart == NULL)
	{
		software_list_device::display_matches(device().machine().config(), image_interface(), path);
		return false;
	}

	// Load the software part
	bool result = call_softlist_load(swpart->info().list(), swpart->info().shortname(), swpart->romdata());

	// Tell the world which part we actually loaded
	astring full_sw_name;
	full_sw_name.printf("%s:%s:%s", swpart->info().list().list_name(), swpart->info().shortname(), swpart->name());

	// check compatibility
	if (!swpart->is_compatible(swpart->info().list()))
		osd_printf_warning("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n", swpart->info().shortname(), swpart->info().list().filter());

	// check requirements and load those images
	const char *requirement = swpart->feature("requirement");
	if (requirement != NULL)
	{
		software_part *req_swpart = find_software_item(requirement, false);
		if (req_swpart != NULL)
		{
			image_interface_iterator imgiter(device().machine().root_device());
			for (device_image_interface *req_image = imgiter.first(); req_image != NULL; req_image = imgiter.next())
			{
				const char *interface = req_image->image_interface();
				if (interface != NULL)
				{
					if (req_swpart->matches_interface(interface))
					{
						const char *option = device().mconfig().options().value(req_image->brief_instance_name());
						// mount only if not already mounted
						if (strlen(option) == 0 && !req_image->filename())
						{
							req_image->set_init_phase();
							req_image->load(requirement);
						}
						break;
					}
				}
			}
		}
	}
	return result;
}
Пример #2
0
void ui_menu_main::populate()
{
	std::string menu_text;

	/* add input menu items */
	item_append("Input (general)", nullptr, 0, (void *)INPUT_GROUPS);

	strprintf(menu_text, "Input (this %s)", emulator_info::get_capstartgamenoun());
	item_append(menu_text.c_str(), nullptr, 0, (void *)INPUT_SPECIFIC);

	/* add optional input-related menus */
	if (machine().ioport().has_analog())
		item_append("Analog Controls", nullptr, 0, (void *)ANALOG);
	if (machine().ioport().has_dips())
		item_append("Dip Switches", nullptr, 0, (void *)SETTINGS_DIP_SWITCHES);
	if (machine().ioport().has_configs())
	{
		strprintf(menu_text, "%s Configuration", emulator_info::get_capstartgamenoun());
		item_append(menu_text.c_str(), nullptr, 0, (void *)SETTINGS_DRIVER_CONFIG);
	}

	/* add bookkeeping menu */
	item_append("Bookkeeping Info", nullptr, 0, (void *)BOOKKEEPING);

	/* add game info menu */
	strprintf(menu_text, "%s Information", emulator_info::get_capstartgamenoun());
	item_append(menu_text.c_str(), nullptr, 0, (void *)GAME_INFO);

	image_interface_iterator imgiter(machine().root_device());
	if (imgiter.first() != nullptr)
	{
		/* add image info menu */
		item_append("Image Information", nullptr, 0, (void *)IMAGE_MENU_IMAGE_INFO);

		/* add file manager menu */
		item_append("File Manager", nullptr, 0, (void *)IMAGE_MENU_FILE_MANAGER);

		/* add tape control menu */
		cassette_device_iterator cassiter(machine().root_device());
		if (cassiter.first() != nullptr)
			item_append("Tape Control", nullptr, 0, (void *)TAPE_CONTROL);
	}

		pty_interface_iterator ptyiter(machine().root_device());
		if (ptyiter.first() != nullptr) {
			item_append("Pseudo terminals", nullptr, 0, (void *)PTY_INFO);
		}
	if (machine().ioport().has_bioses())
		item_append("Bios Selection", nullptr, 0, (void *)BIOS_SELECTION);

	slot_interface_iterator slotiter(machine().root_device());
	if (slotiter.first() != nullptr)
	{
		/* add slot info menu */
		item_append("Slot Devices", nullptr, 0, (void *)SLOT_DEVICES);
	}

	barcode_reader_device_iterator bcriter(machine().root_device());
	if (bcriter.first() != nullptr)
	{
		/* add slot info menu */
		item_append("Barcode Reader", nullptr, 0, (void *)BARCODE_READ);
	}

	network_interface_iterator netiter(machine().root_device());
	if (netiter.first() != nullptr)
	{
		/* add image info menu */
		item_append("Network Devices", nullptr, 0, (void*)NETWORK_DEVICES);
	}

	/* add keyboard mode menu */
	if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post())
		item_append("Keyboard Mode", nullptr, 0, (void *)KEYBOARD_MODE);

	/* add sliders menu */
	item_append("Slider Controls", nullptr, 0, (void *)SLIDERS);

	/* add video options menu */
	item_append("Video Options", nullptr, 0, (machine().render().target_by_index(1) != nullptr) ? (void *)VIDEO_TARGETS : (void *)VIDEO_OPTIONS);

	/* add crosshair options menu */
	if (machine().crosshair().get_usage())
		item_append("Crosshair Options", nullptr, 0, (void *)CROSSHAIR);

	/* add cheat menu */
	if (machine().options().cheat())
		item_append("Cheat", nullptr, 0, (void *)CHEAT);

	// add dats menu
	if (machine().ui().options().enabled_dats() && machine().datfile().has_data(&machine().system()))
		item_append("External DAT View", nullptr, 0, (void *)EXTERNAL_DATS);

	item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);

	/* add favorite menu */
    if (!machine().favorite().isgame_favorite())
		item_append("Add To Favorites", nullptr, 0, (void *)ADD_FAVORITE);
	else
		item_append("Remove From Favorites", nullptr, 0, (void *)REMOVE_FAVORITE);

	item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);

//	menu_text.assign("Quit from ").append(emulator_info::get_capstartgamenoun());
//	item_append(menu_text.c_str(), nullptr, 0, (void *)QUIT_GAME);

	/* add reset and exit menus */
	strprintf(menu_text, "Select New %s", emulator_info::get_capstartgamenoun());
	item_append(menu_text.c_str(), nullptr, 0, (void *)SELECT_GAME);
}
Пример #3
0
void menu_device_config::populate()
{
	std::ostringstream str;
	device_t *dev;

	util::stream_format(str, "[This option is%s currently mounted in the running system]\n\n", m_mounted ? "" : " NOT");
	util::stream_format(str, "Option: %s\n", m_option->name());

	dev = const_cast<machine_config &>(machine().config()).device_add(&machine().config().root_device(), m_option->name(), m_option->devtype(), 0);

	util::stream_format(str, "Device: %s\n", dev->name());
	if (!m_mounted)
		str << "\nIf you select this option, the following items will be enabled:\n";
	else
		str << "\nThe selected option enables the following items:\n";

	// loop over all CPUs
	execute_interface_iterator execiter(*dev);
	if (execiter.count() > 0)
	{
		str << "* CPU:\n";
		std::unordered_set<std::string> exectags;
		for (device_execute_interface &exec : execiter)
		{
			if (!exectags.insert(exec.device().tag()).second)
				continue;

			// get cpu specific clock that takes internal multiplier/dividers into account
			int clock = exec.device().clock();

			// count how many identical CPUs we have
			int count = 1;
			const char *name = exec.device().name();
			for (device_execute_interface &scan : execiter)
			{
				if (exec.device().type() == scan.device().type() && strcmp(name, scan.device().name()) == 0 && exec.device().clock() == scan.device().clock())
					if (exectags.insert(scan.device().tag()).second)
						count++;
			}

			// if more than one, prepend a #x in front of the CPU name
			if (count > 1)
				util::stream_format(str, "  %d" UTF8_MULTIPLY, count);
			else
				str << "  ";
			str << name;

			// display clock in kHz or MHz
			if (clock >= 1000000)
				util::stream_format(str, " %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
			else
				util::stream_format(str, " %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
		}
	}

	// display screen information
	screen_device_iterator scriter(*dev);
	if (scriter.count() > 0)
	{
		str << "* Video:\n";
		for (screen_device &screen : scriter)
		{
			util::stream_format(str, "  Screen '%s': ", screen.tag());

			if (screen.screen_type() == SCREEN_TYPE_VECTOR)
				str << "Vector\n";
			else
			{
				const rectangle &visarea = screen.visible_area();

				util::stream_format(str, "%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz\n",
									visarea.width(), visarea.height(),
									(machine().system().flags & ORIENTATION_SWAP_XY) ? "V" : "H",
									ATTOSECONDS_TO_HZ(screen.frame_period().attoseconds()));
			}
		}
	}

	// loop over all sound chips
	sound_interface_iterator snditer(*dev);
	if (snditer.count() > 0)
	{
		str << "* Sound:\n";
		std::unordered_set<std::string> soundtags;
		for (device_sound_interface &sound : snditer)
		{
			if (!soundtags.insert(sound.device().tag()).second)
				continue;

			// count how many identical sound chips we have
			int count = 1;
			for (device_sound_interface &scan : snditer)
			{
				if (sound.device().type() == scan.device().type() && sound.device().clock() == scan.device().clock())
					if (soundtags.insert(scan.device().tag()).second)
						count++;
			}
			// if more than one, prepend a #x in front of the CPU name
			if (count > 1)
				util::stream_format(str,"  %d" UTF8_MULTIPLY, count);
			else
				str << "  ";
			str << sound.device().name();

			// display clock in kHz or MHz
			int clock = sound.device().clock();
			if (clock >= 1000000)
				util::stream_format(str," %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
			else if (clock != 0)
				util::stream_format(str," %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
			else
				str << '\n';
		}
	}

	// scan for BIOS settings
	int bios = 0;
	if (dev->rom_region())
	{
		std::string bios_str;
		// first loop through roms in search of default bios (shortname)
		for (const rom_entry &rom : dev->rom_region_vector())
			if (ROMENTRY_ISDEFAULT_BIOS(&rom))
				bios_str.assign(ROM_GETNAME(&rom));

		// then loop again to count bios options and to get the default bios complete name
		for (const rom_entry &rom : dev->rom_region_vector())
		{
			if (ROMENTRY_ISSYSTEM_BIOS(&rom))
			{
				bios++;
				if (bios_str.compare(ROM_GETNAME(&rom))==0)
					bios_str.assign(ROM_GETHASHDATA(&rom));
			}
		}

		if (bios)
			util::stream_format(str, "* BIOS settings:\n  %d options    [default: %s]\n", bios, bios_str.c_str());
	}

	int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
	int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
	std::string errors;
	std::ostringstream dips_opt, confs_opt;
	ioport_list portlist;
	for (device_t &iptdev : device_iterator(*dev))
		portlist.append(iptdev, errors);

	// check if the device adds inputs to the system
	for (auto &port : portlist)
		for (ioport_field &field : port.second->fields())
		{
			if (field.type() >= IPT_MAHJONG_FIRST && field.type() < IPT_MAHJONG_LAST)
				input_mj++;
			else if (field.type() >= IPT_HANAFUDA_FIRST && field.type() < IPT_HANAFUDA_LAST)
				input_hana++;
			else if (field.type() >= IPT_GAMBLING_FIRST && field.type() < IPT_GAMBLING_LAST)
				input_gamble++;
			else if (field.type() >= IPT_ANALOG_FIRST && field.type() < IPT_ANALOG_LAST)
				input_analog++;
			else if (field.type() == IPT_ADJUSTER)
				input_adjust++;
			else if (field.type() == IPT_KEYPAD)
				input_keypad++;
			else if (field.type() == IPT_KEYBOARD)
				input_keyboard++;
			else if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
				input++;
			else if (field.type() == IPT_DIPSWITCH)
			{
				dips++;
				dips_opt << "  " << field.name();
				for (ioport_setting &setting : field.settings())
				{
					if (setting.value() == field.defvalue())
					{
						util::stream_format(dips_opt, "    [default: %s]\n", setting.name());
						break;
					}
				}
			}
			else if (field.type() == IPT_CONFIG)
			{
				confs++;
				confs_opt << "  " << field.name();
				for (ioport_setting &setting : field.settings())
				{
					if (setting.value() == field.defvalue())
					{
						util::stream_format(confs_opt, "    [default: %s]\n", setting.name());
						break;
					}
				}
			}
		}

	if (dips)
		str << "* Dispwitch settings:\n" << dips_opt.str();
	if (confs)
		str << "* Configuration settings:\n" << confs_opt.str();
	if (input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard)
		str << "* Input device(s):\n";
	if (input)
		util::stream_format(str, "  User inputs    [%d inputs]\n", input);
	if (input_mj)
		util::stream_format(str, "  Mahjong inputs    [%d inputs]\n", input_mj);
	if (input_hana)
		util::stream_format(str, "  Hanafuda inputs    [%d inputs]\n", input_hana);
	if (input_gamble)
		util::stream_format(str, "  Gambling inputs    [%d inputs]\n", input_gamble);
	if (input_analog)
		util::stream_format(str, "  Analog inputs    [%d inputs]\n", input_analog);
	if (input_adjust)
		util::stream_format(str, "  Adjuster inputs    [%d inputs]\n", input_adjust);
	if (input_keypad)
		util::stream_format(str, "  Keypad inputs    [%d inputs]\n", input_keypad);
	if (input_keyboard)
		util::stream_format(str, "  Keyboard inputs    [%d inputs]\n", input_keyboard);

	image_interface_iterator imgiter(*dev);
	if (imgiter.count() > 0)
	{
		str << "* Media Options:\n";
		for (const device_image_interface &imagedev : imgiter)
			util::stream_format(str, "  %s    [tag: %s]\n", imagedev.image_type_name(), imagedev.device().tag());
	}

	slot_interface_iterator slotiter(*dev);
	if (slotiter.count() > 0)
	{
		str << "* Slot Options:\n";
		for (const device_slot_interface &slot : slotiter)
			util::stream_format(str, "  %s    [default: %s]\n", slot.device().tag(), slot.default_option() ? slot.default_option() : "----");
	}

	if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs
			+ input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0)
			str << "[None]\n";

	const_cast<machine_config &>(machine().config()).device_remove(&machine().config().root_device(), m_option->name());
	item_append(str.str(), "", FLAG_MULTILINE, nullptr);
}
Пример #4
0
void ui_menu_main::populate()
{
	astring menu_text;

	/* add input menu items */
	item_append("Input (general)", NULL, 0, (void *)INPUT_GROUPS);

	menu_text.printf("Input (this %s)",emulator_info::get_capstartgamenoun());
	item_append(menu_text.cstr(), NULL, 0, (void *)INPUT_SPECIFIC);

	/* add optional input-related menus */
	if (machine().ioport().has_analog())
		item_append("Analog Controls", NULL, 0, (void *)ANALOG);
	if (machine().ioport().has_dips())
		item_append("Dip Switches", NULL, 0, (void *)SETTINGS_DIP_SWITCHES);
	if (machine().ioport().has_configs())
	{
		menu_text.printf("%s Configuration",emulator_info::get_capstartgamenoun());
		item_append(menu_text.cstr(), NULL, 0, (void *)SETTINGS_DRIVER_CONFIG);
	}

	/* add bookkeeping menu */
	item_append("Bookkeeping Info", NULL, 0, (void *)BOOKKEEPING);

	/* add game info menu */
	menu_text.printf("%s Information",emulator_info::get_capstartgamenoun());
	item_append(menu_text.cstr(), NULL, 0, (void *)GAME_INFO);

	image_interface_iterator imgiter(machine().root_device());
	if (imgiter.first() != NULL)
	{
		/* add image info menu */
		item_append("Image Information", NULL, 0, (void *)IMAGE_MENU_IMAGE_INFO);

		/* add file manager menu */
		item_append("File Manager", NULL, 0, (void *)IMAGE_MENU_FILE_MANAGER);

		/* add tape control menu */
		cassette_device_iterator cassiter(machine().root_device());
		if (cassiter.first() != NULL)
			item_append("Tape Control", NULL, 0, (void *)TAPE_CONTROL);
	}

	if (machine().ioport().has_bioses())
		item_append("Bios Selection", NULL, 0, (void *)BIOS_SELECTION);

	slot_interface_iterator slotiter(machine().root_device());
	if (slotiter.first() != NULL)
	{
		/* add slot info menu */
		item_append("Slot Devices", NULL, 0, (void *)SLOT_DEVICES);
	}

	barcode_reader_device_iterator bcriter(machine().root_device());
	if (bcriter.first() != NULL)
	{
		/* add slot info menu */
		item_append("Barcode Reader", NULL, 0, (void *)BARCODE_READ);
	}

	network_interface_iterator netiter(machine().root_device());
	if (netiter.first() != NULL)
	{
		/* add image info menu */
		item_append("Network Devices", NULL, 0, (void*)NETWORK_DEVICES);
	}

	/* add keyboard mode menu */
	if (machine().ioport().has_keyboard() && machine().ioport().natkeyboard().can_post())
		item_append("Keyboard Mode", NULL, 0, (void *)KEYBOARD_MODE);

	/* add sliders menu */
	item_append("Slider Controls", NULL, 0, (void *)SLIDERS);

	/* add video options menu */
	item_append("Video Options", NULL, 0, (machine().render().target_by_index(1) != NULL) ? (void *)VIDEO_TARGETS : (void *)VIDEO_OPTIONS);

	/* add crosshair options menu */
	if (crosshair_get_usage(machine()))
		item_append("Crosshair Options", NULL, 0, (void *)CROSSHAIR);

	/* add cheat menu */
	if (machine().options().cheat() && machine().cheat().first() != NULL)
		item_append("Cheat", NULL, 0, (void *)CHEAT);

	/* add reset and exit menus */
	menu_text.printf("Select New %s",emulator_info::get_capstartgamenoun());
	item_append(menu_text.cstr(), NULL, 0, (void *)SELECT_GAME);
}
Пример #5
0
void ui_menu_device_config::populate()
{
	astring string;
	device_t *dev;

	string.printf("[This option is%s currently mounted in the running system]\n\n", m_mounted ? "" : " NOT");
	string.catprintf("Option: %s\n", m_option->name());

	dev = const_cast<machine_config &>(machine().config()).device_add(&machine().config().root_device(), m_option->name(), m_option->devtype(), 0);

	string.catprintf("Device: %s\n", dev->name());
	if (!m_mounted)
		string.cat("\nIf you select this option, the following items will be enabled:\n");
	else
		string.cat("\nThe selected option enables the following items:\n");

	// loop over all CPUs
	execute_interface_iterator execiter(*dev);
	if (execiter.count() > 0)
	{
		string.cat("* CPU:\n");
		tagmap_t<UINT8> exectags;
		for (device_execute_interface *exec = execiter.first(); exec != NULL; exec = execiter.next())
		{
			if (exectags.add(exec->device().tag(), 1, FALSE) == TMERR_DUPLICATE)
				continue;

			// get cpu specific clock that takes internal multiplier/dividers into account
			int clock = exec->device().clock();

			// count how many identical CPUs we have
			int count = 1;
			const char *name = exec->device().name();
			execute_interface_iterator execinneriter(*dev);
			for (device_execute_interface *scan = execinneriter.first(); scan != NULL; scan = execinneriter.next())
			{
				if (exec->device().type() == scan->device().type() && strcmp(name, scan->device().name()) == 0 && exec->device().clock() == scan->device().clock())
					if (exectags.add(scan->device().tag(), 1, FALSE) != TMERR_DUPLICATE)
						count++;
			}

			// if more than one, prepend a #x in front of the CPU name
			if (count > 1)
				string.catprintf("  %d" UTF8_MULTIPLY, count);
			else
				string.cat("  ");
			string.cat(name);

			// display clock in kHz or MHz
			if (clock >= 1000000)
				string.catprintf(" %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
			else
				string.catprintf(" %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
		}
	}

	// display screen information
	screen_device_iterator scriter(*dev);
	if (scriter.count() > 0)
	{
		string.cat("* Video:\n");
		for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next())
		{
			string.catprintf("  Screen '%s': ", screen->tag());

			if (screen->screen_type() == SCREEN_TYPE_VECTOR)
				string.cat("Vector\n");
			else
			{
				const rectangle &visarea = screen->visible_area();

				string.catprintf("%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz\n",
									visarea.width(), visarea.height(),
									(machine().system().flags & ORIENTATION_SWAP_XY) ? "V" : "H",
									ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds));
			}
		}
	}

	// loop over all sound chips
	sound_interface_iterator snditer(*dev);
	if (snditer.count() > 0)
	{
		string.cat("* Sound:\n");
		tagmap_t<UINT8> soundtags;
		for (device_sound_interface *sound = snditer.first(); sound != NULL; sound = snditer.next())
		{
			if (soundtags.add(sound->device().tag(), 1, FALSE) == TMERR_DUPLICATE)
				continue;

			// count how many identical sound chips we have
			int count = 1;
			sound_interface_iterator sndinneriter(*dev);
			for (device_sound_interface *scan = sndinneriter.first(); scan != NULL; scan = sndinneriter.next())
			{
				if (sound->device().type() == scan->device().type() && sound->device().clock() == scan->device().clock())
					if (soundtags.add(scan->device().tag(), 1, FALSE) != TMERR_DUPLICATE)
						count++;
			}
			// if more than one, prepend a #x in front of the CPU name
			if (count > 1)
				string.catprintf("  %d" UTF8_MULTIPLY, count);
			else
				string.cat("  ");
			string.cat(sound->device().name());

			// display clock in kHz or MHz
			int clock = sound->device().clock();
			if (clock >= 1000000)
				string.catprintf(" %d.%06d" UTF8_NBSP "MHz\n", clock / 1000000, clock % 1000000);
			else if (clock != 0)
				string.catprintf(" %d.%03d" UTF8_NBSP "kHz\n", clock / 1000, clock % 1000);
			else
				string.cat("\n");
		}
	}

	// scan for BIOS settings
	int bios = 0;
	if (dev->rom_region())
	{
		astring bios_str;
		// first loop through roms in search of default bios (shortname)
		for (const rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); rom++)
			if (ROMENTRY_ISDEFAULT_BIOS(rom))
				bios_str.cpy(ROM_GETNAME(rom));

		// then loop again to count bios options and to get the default bios complete name
		for (const rom_entry *rom = dev->rom_region(); !ROMENTRY_ISEND(rom); rom++)
		{
			if (ROMENTRY_ISSYSTEM_BIOS(rom))
			{
				bios++;
				if (bios_str == ROM_GETNAME(rom))
					bios_str.cpy(ROM_GETHASHDATA(rom));
			}
		}

		if (bios)
			string.catprintf("* BIOS settings:\n  %d options    [default: %s]\n", bios, bios_str.cstr());
	}

	int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
	int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
	astring errors, dips_opt, confs_opt;
	ioport_list portlist;
	device_iterator iptiter(*dev);
	for (device_t *iptdev = iptiter.first(); iptdev != NULL; iptdev = iptiter.next())
		portlist.append(*iptdev, errors);

	// check if the device adds inputs to the system
	for (ioport_port *port = portlist.first(); port != NULL; port = port->next())
		for (ioport_field *field = port->first_field(); field != NULL; field = field->next())
		{
			if (field->type() >= IPT_MAHJONG_FIRST && field->type() < IPT_MAHJONG_LAST)
				input_mj++;
			else if (field->type() >= IPT_HANAFUDA_FIRST && field->type() < IPT_HANAFUDA_LAST)
				input_hana++;
			else if (field->type() >= IPT_GAMBLING_FIRST && field->type() < IPT_GAMBLING_LAST)
				input_gamble++;
			else if (field->type() >= IPT_ANALOG_FIRST && field->type() < IPT_ANALOG_LAST)
				input_analog++;
			else if (field->type() == IPT_ADJUSTER)
				input_adjust++;
			else if (field->type() == IPT_KEYPAD)
				input_keypad++;
			else if (field->type() == IPT_KEYBOARD)
				input_keyboard++;
			else if (field->type() >= IPT_START1 && field->type() < IPT_UI_FIRST)
				input++;
			else if (field->type() == IPT_DIPSWITCH)
			{
				dips++;
				dips_opt.cat("  ").cat(field->name());
				for (ioport_setting *setting = field->first_setting(); setting != NULL; setting = setting->next())
				{
					if (setting->value() == field->defvalue())
					{
						dips_opt.catprintf("    [default: %s]\n", setting->name());
						break;
					}
				}
			}
			else if (field->type() == IPT_CONFIG)
			{
				confs++;
				confs_opt.cat("  ").cat(field->name());
				for (ioport_setting *setting = field->first_setting(); setting != NULL; setting = setting->next())
				{
					if (setting->value() == field->defvalue())
					{
						confs_opt.catprintf("    [default: %s]\n", setting->name());
						break;
					}
				}
			}
		}

	if (dips)
		string.cat("* Dispwitch settings:\n").cat(dips_opt);
	if (confs)
		string.cat("* Configuration settings:\n").cat(confs_opt);
	if (input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard)
		string.cat("* Input device(s):\n");
	if (input)
		string.catprintf("  User inputs    [%d inputs]\n", input);
	if (input_mj)
		string.catprintf("  Mahjong inputs    [%d inputs]\n", input_mj);
	if (input_hana)
		string.catprintf("  Hanafuda inputs    [%d inputs]\n", input_hana);
	if (input_gamble)
		string.catprintf("  Gambling inputs    [%d inputs]\n", input_gamble);
	if (input_analog)
		string.catprintf("  Analog inputs    [%d inputs]\n", input_analog);
	if (input_adjust)
		string.catprintf("  Adjuster inputs    [%d inputs]\n", input_adjust);
	if (input_keypad)
		string.catprintf("  Keypad inputs    [%d inputs]\n", input_keypad);
	if (input_keyboard)
		string.catprintf("  Keyboard inputs    [%d inputs]\n", input_keyboard);

	image_interface_iterator imgiter(*dev);
	if (imgiter.count() > 0)
	{
		string.cat("* Media Options:\n");
		for (const device_image_interface *imagedev = imgiter.first(); imagedev != NULL; imagedev = imgiter.next())
			string.catprintf("  %s    [tag: %s]\n", imagedev->image_type_name(), imagedev->device().tag());
	}

	slot_interface_iterator slotiter(*dev);
	if (slotiter.count() > 0)
	{
		string.cat("* Slot Options:\n");
		for (const device_slot_interface *slot = slotiter.first(); slot != NULL; slot = slotiter.next())
			string.catprintf("  %s    [default: %s]\n", slot->device().tag(), slot->default_option() ? slot->default_option() : "----");
	}

	if ((execiter.count() + scriter.count() + snditer.count() + imgiter.count() + slotiter.count() + bios + dips + confs
			+ input + input_mj + input_hana + input_gamble + input_analog + input_adjust + input_keypad + input_keyboard) == 0)
		string.cat("[None]\n");

	const_cast<machine_config &>(machine().config()).device_remove(&machine().config().root_device(), m_option->name());
	item_append(string, NULL, MENU_FLAG_MULTILINE, NULL);
}