Merge pull request #1218 from ajrhacker/machine_info

UI-related cleanup (nw)
This commit is contained in:
Vas Crabb 2016-08-10 10:45:30 +10:00 committed by GitHub
commit d192a0a475
10 changed files with 379 additions and 346 deletions

View File

@ -208,23 +208,6 @@ void image_manager::options_extract()
}
/*-------------------------------------------------
image_mandatory_scan - search for devices which
need an image to be loaded
-------------------------------------------------*/
std::string &image_manager::mandatory_scan(std::string &mandatory)
{
mandatory.clear();
// make sure that any required image has a mounted file
for (device_image_interface &image : image_interface_iterator(machine().root_device()))
{
if (image.filename() == nullptr && image.must_be_loaded())
mandatory.append("\"").append(image.instance_name()).append("\", ");
}
return mandatory;
}
/*-------------------------------------------------
postdevice_init - initialize devices for a specific
running_machine

View File

@ -23,7 +23,6 @@ public:
void unload_all();
void postdevice_init();
std::string &mandatory_scan(std::string &mandatory);
// getters
running_machine &machine() const { return m_machine; }

View File

@ -2450,10 +2450,6 @@ ioport_manager::ioport_manager(running_machine &machine)
m_timecode_file(machine.options().input_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS),
m_timecode_count(0),
m_timecode_last_time(attotime::zero),
m_has_configs(false),
m_has_analog(false),
m_has_dips(false),
m_has_bioses(false),
m_autofire_toggle(false),
m_autofire_delay(3) // 1 seems too fast for a bunch of games
{
@ -2534,29 +2530,6 @@ time_t ioport_manager::initialize()
// register callbacks for when we load configurations
machine().configuration().config_register("input", config_saveload_delegate(FUNC(ioport_manager::load_config), this), config_saveload_delegate(FUNC(ioport_manager::save_config), this));
// calculate "has..." values
{
m_has_configs = false;
m_has_analog = false;
m_has_dips = false;
m_has_bioses = false;
// scan the input port array to see what options we need to enable
for (auto &port : m_portlist)
for (ioport_field &field : port.second->fields())
{
if (field.type() == IPT_DIPSWITCH)
m_has_dips = true;
if (field.type() == IPT_CONFIG)
m_has_configs = true;
if (field.is_analog())
m_has_analog = true;
}
for (device_t &device : device_iterator(machine().root_device()))
for (const rom_entry &rom : device.rom_region_vector())
if (ROMENTRY_ISSYSTEM_BIOS(&rom)) { m_has_bioses= true; break; }
}
// open playback and record files if specified
time_t basetime = playback_init();
record_init();

View File

@ -1474,12 +1474,6 @@ public:
bool safe_to_read() const { return m_safe_to_read; }
natural_keyboard &natkeyboard() { return m_natkeyboard; }
// has... getters
bool has_configs() const { return m_has_configs; }
bool has_analog() const { return m_has_analog; }
bool has_dips() const { return m_has_dips; }
bool has_bioses() const { return m_has_bioses; }
// type helpers
const simple_list<input_type_entry> &types() const { return m_typelist; }
bool type_pressed(ioport_type type, int player = 0);
@ -1570,12 +1564,6 @@ private:
int m_timecode_count;
attotime m_timecode_last_time;
// has...
bool m_has_configs;
bool m_has_analog;
bool m_has_dips;
bool m_has_bioses;
// autofire
bool m_autofire_toggle; // autofire toggle
int m_autofire_delay; // autofire delay

View File

@ -2395,10 +2395,6 @@ void lua_engine::initialize()
.addFunction ("select_next_state", &cheat_entry::select_next_state)
.endClass()
.beginClass <ioport_manager> ("ioport")
.addFunction ("has_configs", &ioport_manager::has_configs)
.addFunction ("has_analog", &ioport_manager::has_analog)
.addFunction ("has_dips", &ioport_manager::has_dips)
.addFunction ("has_bioses", &ioport_manager::has_bioses)
.addFunction ("has_keyboard", &ioport_manager::has_keyboard)
.addFunction ("count_players", &ioport_manager::count_players)
.addProperty <luabridge::LuaRef, void> ("ports", &lua_engine::l_ioport_get_ports)

View File

@ -13,9 +13,328 @@
#include "ui/info.h"
#include "ui/ui.h"
#include "drivenum.h"
#include "softlist.h"
namespace ui {
//-------------------------------------------------
// machine_info - constructor
//-------------------------------------------------
machine_info::machine_info(running_machine &machine)
: m_machine(machine)
{
// calculate "has..." values
m_has_configs = false;
m_has_analog = false;
m_has_dips = false;
m_has_bioses = false;
// scan the input port array to see what options we need to enable
for (auto &port : machine.ioport().ports())
for (ioport_field &field : port.second->fields())
{
if (field.type() == IPT_DIPSWITCH)
m_has_dips = true;
if (field.type() == IPT_CONFIG)
m_has_configs = true;
if (field.is_analog())
m_has_analog = true;
}
for (device_t &device : device_iterator(machine.root_device()))
for (const rom_entry &rom : device.rom_region_vector())
if (ROMENTRY_ISSYSTEM_BIOS(&rom)) { m_has_bioses = true; break; }
}
/***************************************************************************
TEXT GENERATORS
***************************************************************************/
//-------------------------------------------------
// warnings_string - print the warning flags
// text to the given buffer
//-------------------------------------------------
std::string machine_info::warnings_string()
{
constexpr UINT32 warning_flags = ( MACHINE_NOT_WORKING |
MACHINE_UNEMULATED_PROTECTION |
MACHINE_MECHANICAL |
MACHINE_WRONG_COLORS |
MACHINE_IMPERFECT_COLORS |
MACHINE_REQUIRES_ARTWORK |
MACHINE_NO_SOUND |
MACHINE_IMPERFECT_SOUND |
MACHINE_IMPERFECT_GRAPHICS |
MACHINE_IMPERFECT_KEYBOARD |
MACHINE_NO_COCKTAIL |
MACHINE_IS_INCOMPLETE |
MACHINE_NO_SOUND_HW );
// if no warnings, nothing to return
if (m_machine.rom_load().warnings() == 0 && m_machine.rom_load().knownbad() == 0 && !(m_machine.system().flags & warning_flags) && m_machine.rom_load().software_load_warnings_message().length() == 0)
return std::string();
std::ostringstream buf;
// add a warning if any ROMs were loaded with warnings
if (m_machine.rom_load().warnings() > 0)
{
buf << _("One or more ROMs/CHDs for this machine are incorrect. The machine may not run correctly.\n");
if (m_machine.system().flags & warning_flags)
buf << "\n";
}
if (m_machine.rom_load().software_load_warnings_message().length()>0) {
buf << m_machine.rom_load().software_load_warnings_message();
if (m_machine.system().flags & warning_flags)
buf << "\n";
}
// if we have at least one warning flag, print the general header
if ((m_machine.system().flags & warning_flags) || m_machine.rom_load().knownbad() > 0)
{
buf << _("There are known problems with this machine\n\n");
// add a warning if any ROMs are flagged BAD_DUMP/NO_DUMP
if (m_machine.rom_load().knownbad() > 0) {
buf << _("One or more ROMs/CHDs for this machine have not been correctly dumped.\n");
}
// add one line per warning flag
if (m_machine.system().flags & MACHINE_IMPERFECT_KEYBOARD)
buf << _("The keyboard emulation may not be 100% accurate.\n");
if (m_machine.system().flags & MACHINE_IMPERFECT_COLORS)
buf << _("The colors aren't 100% accurate.\n");
if (m_machine.system().flags & MACHINE_WRONG_COLORS)
buf << _("The colors are completely wrong.\n");
if (m_machine.system().flags & MACHINE_IMPERFECT_GRAPHICS)
buf << _("The video emulation isn't 100% accurate.\n");
if (m_machine.system().flags & MACHINE_IMPERFECT_SOUND)
buf << _("The sound emulation isn't 100% accurate.\n");
if (m_machine.system().flags & MACHINE_NO_SOUND) {
buf << _("The machine lacks sound.\n");
}
if (m_machine.system().flags & MACHINE_NO_COCKTAIL)
buf << _("Screen flipping in cocktail mode is not supported.\n");
// check if external artwork is present before displaying this warning?
if (m_machine.system().flags & MACHINE_REQUIRES_ARTWORK) {
buf << _("The machine requires external artwork files\n");
}
if (m_machine.system().flags & MACHINE_IS_INCOMPLETE )
{
buf << _("This machine was never completed. It may exhibit strange behavior or missing elements that are not bugs in the emulation.\n");
}
if (m_machine.system().flags & MACHINE_NO_SOUND_HW )
{
buf << _("This machine has no sound hardware, MAME will produce no sounds, this is expected behaviour.\n");
}
// if there's a NOT WORKING, UNEMULATED PROTECTION or GAME MECHANICAL warning, make it stronger
if (m_machine.system().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL))
{
// add the strings for these warnings
if (m_machine.system().flags & MACHINE_UNEMULATED_PROTECTION) {
buf << _("The machine has protection which isn't fully emulated.\n");
}
if (m_machine.system().flags & MACHINE_NOT_WORKING) {
buf << _("\nTHIS MACHINE DOESN'T WORK. The emulation for this machine is not yet complete. "
"There is nothing you can do to fix this problem except wait for the developers to improve the emulation.\n");
}
if (m_machine.system().flags & MACHINE_MECHANICAL) {
buf << _("\nCertain elements of this machine cannot be emulated as it requires actual physical interaction or consists of mechanical devices. "
"It is not possible to fully play this machine.\n");
}
// find the parent of this driver
driver_enumerator drivlist(m_machine.options());
int maindrv = drivlist.find(m_machine.system());
int clone_of = drivlist.non_bios_clone(maindrv);
if (clone_of != -1)
maindrv = clone_of;
// scan the driver list for any working clones and add them
bool foundworking = false;
while (drivlist.next())
if (drivlist.current() == maindrv || drivlist.clone() == maindrv)
if ((drivlist.driver().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) == 0)
{
// this one works, add a header and display the name of the clone
if (!foundworking) {
buf << _("\n\nThere are working clones of this machine: ");
}
else
buf << ", ";
buf << drivlist.driver().name;
foundworking = true;
}
if (foundworking)
buf << "\n";
}
}
// add the 'press OK' string
buf << _("\n\nPress any key to continue");
return buf.str();
}
//-------------------------------------------------
// game_info_string - return the game info text
//-------------------------------------------------
std::string machine_info::game_info_string()
{
std::ostringstream buf;
// print description, manufacturer, and CPU:
util::stream_format(buf, _("%1$s\n%2$s %3$s\nDriver: %4$s\n\nCPU:\n"),
m_machine.system().description,
m_machine.system().year,
m_machine.system().manufacturer,
core_filename_extract_base(m_machine.system().source_file));
// loop over all CPUs
execute_interface_iterator execiter(m_machine.root_device());
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
// display clock in kHz or MHz
util::stream_format(buf,
(count > 1) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s %3$d.%4$0*5$d%6$s\n",
count,
name,
(clock >= 1000000) ? (clock / 1000000) : (clock / 1000),
(clock >= 1000000) ? (clock % 1000000) : (clock % 1000),
(clock >= 1000000) ? 6 : 3,
(clock >= 1000000) ? _("MHz") : _("kHz"));
}
// loop over all sound chips
sound_interface_iterator snditer(m_machine.root_device());
std::unordered_set<std::string> soundtags;
bool found_sound = false;
for (device_sound_interface &sound : snditer)
{
if (!soundtags.insert(sound.device().tag()).second)
continue;
// append the Sound: string
if (!found_sound)
buf << _("\nSound:\n");
found_sound = true;
// 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
// display clock in kHz or MHz
int clock = sound.device().clock();
util::stream_format(buf,
(count > 1)
? ((clock != 0) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%1$d" UTF8_MULTIPLY "%2$s\n")
: ((clock != 0) ? "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s\n"),
count,
sound.device().name(),
(clock >= 1000000) ? (clock / 1000000) : (clock / 1000),
(clock >= 1000000) ? (clock % 1000000) : (clock % 1000),
(clock >= 1000000) ? 6 : 3,
(clock >= 1000000) ? _("MHz") : _("kHz"));
}
// display screen information
buf << _("\nVideo:\n");
screen_device_iterator scriter(m_machine.root_device());
int scrcount = scriter.count();
if (scrcount == 0)
buf << _("None\n");
else
{
for (screen_device &screen : scriter)
{
std::string detail;
if (screen.screen_type() == SCREEN_TYPE_VECTOR)
detail = _("Vector");
else
{
const rectangle &visarea = screen.visible_area();
detail = string_format("%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz",
visarea.width(), visarea.height(),
(m_machine.system().flags & ORIENTATION_SWAP_XY) ? "V" : "H",
ATTOSECONDS_TO_HZ(screen.frame_period().attoseconds()));
}
util::stream_format(buf,
(scrcount > 1) ? _("%1$s: %2$s\n") : _("%2$s\n"),
get_screen_desc(screen), detail);
}
}
return buf.str();
}
//-------------------------------------------------
// mandatory_images - search for devices which
// need an image to be loaded
//-------------------------------------------------
std::string machine_info::mandatory_images()
{
std::ostringstream buf;
// make sure that any required image has a mounted file
for (device_image_interface &image : image_interface_iterator(m_machine.root_device()))
{
if (image.filename() == nullptr && image.must_be_loaded())
buf << "\"" << image.instance_name() << "\", ";
}
return buf.str();
}
//-------------------------------------------------
// get_screen_desc - returns the description for
// a given screen
//-------------------------------------------------
std::string machine_info::get_screen_desc(screen_device &screen)
{
if (screen_device_iterator(m_machine.root_device()).count() > 1)
return string_format(_("Screen '%1$s'"), screen.tag());
else
return _("Screen");
}
/*-------------------------------------------------
menu_game_info - handle the game information
menu
@ -31,8 +350,8 @@ menu_game_info::~menu_game_info()
void menu_game_info::populate()
{
std::string tempstring;
item_append(ui().game_info_astring(tempstring), "", FLAG_MULTILINE, nullptr);
std::string tempstring = ui().machine_info().game_info_string();
item_append(std::move(tempstring), "", FLAG_MULTILINE, nullptr);
}
void menu_game_info::handle()

View File

@ -16,6 +16,36 @@
#include "ui/menu.h"
namespace ui {
class machine_info
{
public:
// construction
machine_info(running_machine &machine);
// has... getters
bool has_configs() const { return m_has_configs; }
bool has_analog() const { return m_has_analog; }
bool has_dips() const { return m_has_dips; }
bool has_bioses() const { return m_has_bioses; }
// text generators
std::string warnings_string();
std::string game_info_string();
std::string mandatory_images();
std::string get_screen_desc(screen_device &screen);
private:
// reference to machine
running_machine & m_machine;
// has...
bool m_has_configs;
bool m_has_analog;
bool m_has_dips;
bool m_has_bioses;
};
class menu_game_info : public menu
{
public:

View File

@ -56,11 +56,11 @@ void menu_main::populate()
item_append(_("Input (this Machine)"), "", 0, (void *)INPUT_SPECIFIC);
/* add optional input-related menus */
if (machine().ioport().has_analog())
if (ui().machine_info().has_analog())
item_append(_("Analog Controls"), "", 0, (void *)ANALOG);
if (machine().ioport().has_dips())
if (ui().machine_info().has_dips())
item_append(_("Dip Switches"), "", 0, (void *)SETTINGS_DIP_SWITCHES);
if (machine().ioport().has_configs())
if (ui().machine_info().has_configs())
{
item_append(_("Machine Configuration"), "", 0, (void *)SETTINGS_DRIVER_CONFIG);
}
@ -92,7 +92,7 @@ void menu_main::populate()
if (pty_interface_iterator(machine().root_device()).first() != nullptr)
item_append(_("Pseudo terminals"), "", 0, (void *)PTY_INFO);
if (machine().ioport().has_bioses())
if (ui().machine_info().has_bioses())
item_append(_("Bios Selection"), "", 0, (void *)BIOS_SELECTION);
/* add slot info menu */

View File

@ -21,13 +21,13 @@
#include "rendfont.h"
#include "uiinput.h"
#include "ui/ui.h"
#include "ui/info.h"
#include "ui/menu.h"
#include "ui/mainmenu.h"
#include "ui/filemngr.h"
#include "ui/sliders.h"
#include "ui/viewgfx.h"
#include "imagedev/cassette.h"
#include "image.h"
/***************************************************************************
@ -186,6 +186,10 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
{
}
mame_ui_manager::~mame_ui_manager()
{
}
void mame_ui_manager::init()
{
load_ui_options();
@ -240,6 +244,8 @@ void mame_ui_manager::exit()
void mame_ui_manager::initialize(running_machine &machine)
{
m_machine_info = std::make_unique<ui::machine_info>(machine);
// initialize the on-screen display system
slider_list = slider_init(machine);
if (slider_list.size() > 0)
@ -295,12 +301,15 @@ void mame_ui_manager::display_startup_screens(bool first_time)
{
// default to standard colors
messagebox_backcolor = UI_BACKGROUND_COLOR;
messagebox_text.clear();
// pick the next state
switch (state)
{
case 0:
if (show_warnings && warnings_string(messagebox_text).length() > 0)
if (show_warnings)
messagebox_text = machine_info().warnings_string();
if (!messagebox_text.empty())
{
set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
if (machine().system().flags & (MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS | MACHINE_REQUIRES_ARTWORK | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_KEYBOARD | MACHINE_NO_SOUND))
@ -311,12 +320,16 @@ void mame_ui_manager::display_startup_screens(bool first_time)
break;
case 1:
if (show_gameinfo && game_info_astring(messagebox_text).length() > 0)
if (show_gameinfo)
messagebox_text = machine_info().game_info_string();
if (!messagebox_text.empty())
set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
break;
case 2:
if (show_mandatory_fileman && machine().image().mandatory_scan(messagebox_text).length() > 0)
if (show_mandatory_fileman)
messagebox_text = machine_info().mandatory_images();
if (!messagebox_text.empty())
{
std::string warning;
warning.assign(_("This driver requires images to be loaded in the following device(s): ")).append(messagebox_text.substr(0, messagebox_text.length() - 2));
@ -745,259 +758,6 @@ bool mame_ui_manager::is_menu_active(void)
}
/***************************************************************************
TEXT GENERATORS
***************************************************************************/
//-------------------------------------------------
// warnings_string - print the warning flags
// text to the given buffer
//-------------------------------------------------
std::string &mame_ui_manager::warnings_string(std::string &str)
{
#define WARNING_FLAGS ( MACHINE_NOT_WORKING | \
MACHINE_UNEMULATED_PROTECTION | \
MACHINE_MECHANICAL | \
MACHINE_WRONG_COLORS | \
MACHINE_IMPERFECT_COLORS | \
MACHINE_REQUIRES_ARTWORK | \
MACHINE_NO_SOUND | \
MACHINE_IMPERFECT_SOUND | \
MACHINE_IMPERFECT_GRAPHICS | \
MACHINE_IMPERFECT_KEYBOARD | \
MACHINE_NO_COCKTAIL| \
MACHINE_IS_INCOMPLETE| \
MACHINE_NO_SOUND_HW )
str.clear();
// if no warnings, nothing to return
if (machine().rom_load().warnings() == 0 && machine().rom_load().knownbad() == 0 && !(machine().system().flags & WARNING_FLAGS) && machine().rom_load().software_load_warnings_message().length() == 0)
return str;
// add a warning if any ROMs were loaded with warnings
if (machine().rom_load().warnings() > 0)
{
str.append(_("One or more ROMs/CHDs for this machine are incorrect. The machine may not run correctly.\n"));
if (machine().system().flags & WARNING_FLAGS)
str.append("\n");
}
if (machine().rom_load().software_load_warnings_message().length()>0) {
str.append(machine().rom_load().software_load_warnings_message());
if (machine().system().flags & WARNING_FLAGS)
str.append("\n");
}
// if we have at least one warning flag, print the general header
if ((machine().system().flags & WARNING_FLAGS) || machine().rom_load().knownbad() > 0)
{
str.append(_("There are known problems with this machine\n\n"));
// add a warning if any ROMs are flagged BAD_DUMP/NO_DUMP
if (machine().rom_load().knownbad() > 0) {
str.append(_("One or more ROMs/CHDs for this machine have not been correctly dumped.\n"));
}
// add one line per warning flag
if (machine().system().flags & MACHINE_IMPERFECT_KEYBOARD)
str.append(_("The keyboard emulation may not be 100% accurate.\n"));
if (machine().system().flags & MACHINE_IMPERFECT_COLORS)
str.append(_("The colors aren't 100% accurate.\n"));
if (machine().system().flags & MACHINE_WRONG_COLORS)
str.append(_("The colors are completely wrong.\n"));
if (machine().system().flags & MACHINE_IMPERFECT_GRAPHICS)
str.append(_("The video emulation isn't 100% accurate.\n"));
if (machine().system().flags & MACHINE_IMPERFECT_SOUND)
str.append(_("The sound emulation isn't 100% accurate.\n"));
if (machine().system().flags & MACHINE_NO_SOUND) {
str.append(_("The machine lacks sound.\n"));
}
if (machine().system().flags & MACHINE_NO_COCKTAIL)
str.append(_("Screen flipping in cocktail mode is not supported.\n"));
// check if external artwork is present before displaying this warning?
if (machine().system().flags & MACHINE_REQUIRES_ARTWORK) {
str.append(_("The machine requires external artwork files\n"));
}
if (machine().system().flags & MACHINE_IS_INCOMPLETE )
{
str.append(_("This machine was never completed. It may exhibit strange behavior or missing elements that are not bugs in the emulation.\n"));
}
if (machine().system().flags & MACHINE_NO_SOUND_HW )
{
str.append(_("This machine has no sound hardware, MAME will produce no sounds, this is expected behaviour.\n"));
}
// if there's a NOT WORKING, UNEMULATED PROTECTION or GAME MECHANICAL warning, make it stronger
if (machine().system().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL))
{
// add the strings for these warnings
if (machine().system().flags & MACHINE_UNEMULATED_PROTECTION) {
str.append(_("The machine has protection which isn't fully emulated.\n"));
}
if (machine().system().flags & MACHINE_NOT_WORKING) {
str.append(_("\nTHIS MACHINE DOESN'T WORK. The emulation for this machine is not yet complete. "
"There is nothing you can do to fix this problem except wait for the developers to improve the emulation.\n"));
}
if (machine().system().flags & MACHINE_MECHANICAL) {
str.append(_("\nCertain elements of this machine cannot be emulated as it requires actual physical interaction or consists of mechanical devices. "
"It is not possible to fully play this machine.\n"));
}
// find the parent of this driver
driver_enumerator drivlist(machine().options());
int maindrv = drivlist.find(machine().system());
int clone_of = drivlist.non_bios_clone(maindrv);
if (clone_of != -1)
maindrv = clone_of;
// scan the driver list for any working clones and add them
bool foundworking = false;
while (drivlist.next())
if (drivlist.current() == maindrv || drivlist.clone() == maindrv)
if ((drivlist.driver().flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_MECHANICAL)) == 0)
{
// this one works, add a header and display the name of the clone
if (!foundworking) {
str.append(_("\n\nThere are working clones of this machine: "));
}
else
str.append(", ");
str.append(drivlist.driver().name);
foundworking = true;
}
if (foundworking)
str.append("\n");
}
}
// add the 'press OK' string
str.append(_("\n\nPress any key to continue"));
return str;
}
//-------------------------------------------------
// game_info_std::string - populate an allocated
// string with the game info text
//-------------------------------------------------
std::string &mame_ui_manager::game_info_astring(std::string &str)
{
std::ostringstream buf;
// print description, manufacturer, and CPU:
util::stream_format(buf, _("%1$s\n%2$s %3$s\nDriver: %4$s\n\nCPU:\n"),
machine().system().description,
machine().system().year,
machine().system().manufacturer,
core_filename_extract_base(machine().system().source_file));
// loop over all CPUs
execute_interface_iterator execiter(machine().root_device());
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
// display clock in kHz or MHz
util::stream_format(buf,
(count > 1) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s %3$d.%4$0*5$d%6$s\n",
count,
name,
(clock >= 1000000) ? (clock / 1000000) : (clock / 1000),
(clock >= 1000000) ? (clock % 1000000) : (clock % 1000),
(clock >= 1000000) ? 6 : 3,
(clock >= 1000000) ? _("MHz") : _("kHz"));
}
// loop over all sound chips
sound_interface_iterator snditer(machine().root_device());
std::unordered_set<std::string> soundtags;
bool found_sound = false;
for (device_sound_interface &sound : snditer)
{
if (!soundtags.insert(sound.device().tag()).second)
continue;
// append the Sound: string
if (!found_sound)
buf << _("\nSound:\n");
found_sound = true;
// 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
// display clock in kHz or MHz
int clock = sound.device().clock();
util::stream_format(buf,
(count > 1)
? ((clock != 0) ? "%1$d" UTF8_MULTIPLY "%2$s %3$d.%4$0*5$d%6$s\n" : "%1$d" UTF8_MULTIPLY "%2$s\n")
: ((clock != 0) ? "%2$s %3$d.%4$0*5$d%6$s\n" : "%2$s\n"),
count,
sound.device().name(),
(clock >= 1000000) ? (clock / 1000000) : (clock / 1000),
(clock >= 1000000) ? (clock % 1000000) : (clock % 1000),
(clock >= 1000000) ? 6 : 3,
(clock >= 1000000) ? _("MHz") : _("kHz"));
}
// display screen information
buf << _("\nVideo:\n");
screen_device_iterator scriter(machine().root_device());
int scrcount = scriter.count();
if (scrcount == 0)
buf << _("None\n");
else
{
for (screen_device &screen : scriter)
{
std::string detail;
if (screen.screen_type() == SCREEN_TYPE_VECTOR)
detail = _("Vector");
else
{
const rectangle &visarea = screen.visible_area();
detail = string_format("%d " UTF8_MULTIPLY " %d (%s) %f" UTF8_NBSP "Hz",
visarea.width(), visarea.height(),
(machine().system().flags & ORIENTATION_SWAP_XY) ? "V" : "H",
ATTOSECONDS_TO_HZ(screen.frame_period().attoseconds()));
}
util::stream_format(buf,
(scrcount > 1) ? _("%1$s: %2$s\n") : _("%2$s\n"),
slider_get_screen_desc(screen), detail);
}
}
return str = buf.str();
}
/***************************************************************************
UI HANDLERS
@ -1043,7 +803,7 @@ UINT32 mame_ui_manager::handler_messagebox_anykey(render_container &container)
}
//-------------------------------------------------3
//-------------------------------------------------
// process_natural_keyboard - processes any
// natural keyboard input
//-------------------------------------------------
@ -1758,7 +1518,7 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
int defxoffset = floor(screen.xoffset() * 1000.0f + 0.5f);
int defyoffset = floor(screen.yoffset() * 1000.0f + 0.5f);
void *param = (void *)&screen;
std::string screen_desc = slider_get_screen_desc(screen);
std::string screen_desc = machine_info().get_screen_desc(screen);
// add refresh rate tweaker
if (machine.options().cheat())
@ -2317,19 +2077,6 @@ INT32 mame_ui_manager::slider_beam_intensity_weight(running_machine &machine, vo
}
//-------------------------------------------------
// slider_get_screen_desc - returns the
// description for a given screen
//-------------------------------------------------
std::string mame_ui_manager::slider_get_screen_desc(screen_device &screen)
{
if (screen_device_iterator(screen.machine().root_device()).count() > 1)
return string_format(_("Screen '%1$s'"), screen.tag());
else
return _("Screen");
}
//-------------------------------------------------
// slider_crossscale - crosshair scale slider
// callback

View File

@ -26,7 +26,7 @@
namespace ui {
class menu_item;
class machine_info;
} // namespace ui
/***************************************************************************
@ -152,6 +152,7 @@ public:
// construction/destruction
mame_ui_manager(running_machine &machine);
~mame_ui_manager();
void init();
@ -159,6 +160,7 @@ public:
running_machine &machine() const { return m_machine; }
bool single_step() const { return m_single_step; }
ui_options &options() { return m_ui_options; }
ui::machine_info &machine_info() const { assert(m_machine_info != nullptr); return *m_machine_info; }
// setters
void set_single_step(bool single_step) { m_single_step = single_step; }
@ -213,9 +215,6 @@ public:
void start_save_state();
void start_load_state();
// print the game info string into a buffer
std::string &game_info_astring(std::string &str);
// slider controls
std::vector<ui::menu_item>& get_slider_list(void);
@ -249,6 +248,8 @@ private:
bool m_load_save_hold;
ui_options m_ui_options;
std::unique_ptr<ui::machine_info> m_machine_info;
// static variables
static std::string messagebox_text;
static std::string messagebox_poptext;
@ -257,9 +258,6 @@ private:
static std::vector<ui::menu_item> slider_list;
static slider_state *slider_current;
// text generators
std::string &warnings_string(std::string &buffer);
// UI handlers
UINT32 handler_messagebox(render_container &container);
UINT32 handler_messagebox_anykey(render_container &container);