mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
Merge pull request #1218 from ajrhacker/machine_info
UI-related cleanup (nw)
This commit is contained in:
commit
d192a0a475
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user