From 5bff739d72161cd176cfea63a30545ce323bd52c Mon Sep 17 00:00:00 2001 From: etabeta78 Date: Sun, 18 Jan 2015 12:10:51 +0100 Subject: [PATCH] ui: stop the game selector reporting systems with no roms as missing files. [Fabio Priuli] ui: when launching systems with mandatory carts, either from command line or from the game selector, prompt the user with the file manager menu so that he can mount a game where needed, instead of killing emulation with an error. [Fabio Priuli] out of whatsnew: it is now finally possible to launch nes and snes and a2600 (and a few more) from the internal system selector! also MESS doesn't error out anymore if you launch such systems with no carts mounted from command line. in short: emulation finally behaves as users typically expect! --- src/emu/image.c | 25 ++++++++++++++----------- src/emu/image.h | 1 + src/emu/ui/filemngr.c | 34 +++++++++++++++++++++++++++++++++- src/emu/ui/filemngr.h | 7 ++++++- src/emu/ui/imgcntrl.c | 2 -- src/emu/ui/mainmenu.c | 2 +- src/emu/ui/selgame.c | 2 +- src/emu/ui/ui.c | 12 +++++++++++- 8 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/emu/image.c b/src/emu/image.c index 4ae8057cec8..943ab30e4fe 100644 --- a/src/emu/image.c +++ b/src/emu/image.c @@ -237,21 +237,24 @@ void image_device_init(running_machine &machine) } } } +} +/*------------------------------------------------- + image_mandatory_scan - search for devices which + need an image to be loaded + -------------------------------------------------*/ + +astring &image_mandatory_scan(running_machine &machine, astring &mandatory) +{ + mandatory.reset(); + // make sure that any required image has a mounted file + image_interface_iterator iter(machine.root_device()); for (device_image_interface *image = iter.first(); image != NULL; image = iter.next()) { - /* is an image specified for this image */ - image_name = image->filename(); - - if (!((image_name != NULL) && (image_name[0] != '\0'))) - { - /* no image... must this device be loaded? */ - if (image->must_be_loaded()) - { - fatalerror_exitcode(machine, MAMERR_DEVICE, "Driver requires that device \"%s\" must have an image to load", image->instance_name()); - } - } + if (image->filename() == NULL && image->must_be_loaded()) + mandatory.cat("\"").cat(image->instance_name()).cat("\", "); } + return mandatory; } /*------------------------------------------------- diff --git a/src/emu/image.h b/src/emu/image.h index 4b3e5c1e05b..140a25473b7 100644 --- a/src/emu/image.h +++ b/src/emu/image.h @@ -20,6 +20,7 @@ void image_init(running_machine &machine); void image_postdevice_init(running_machine &machine); +astring &image_mandatory_scan(running_machine &machine, astring &mandatory); extern struct io_procs image_ioprocs; diff --git a/src/emu/ui/filemngr.c b/src/emu/ui/filemngr.c index 00390696963..47eef69154c 100644 --- a/src/emu/ui/filemngr.c +++ b/src/emu/ui/filemngr.c @@ -20,6 +20,7 @@ #include "ui/swlist.h" #include "ui/filemngr.h" #include "ui/filesel.h" +#include "ui/miscmenu.h" /*************************************************************************** @@ -30,8 +31,14 @@ // ctor //------------------------------------------------- -ui_menu_file_manager::ui_menu_file_manager(running_machine &machine, render_container *container) : ui_menu(machine, container) +ui_menu_file_manager::ui_menu_file_manager(running_machine &machine, render_container *container, const char *warnings) : ui_menu(machine, container) { + // This warning string is used when accessing from the force_file_manager call, i.e. + // when the file manager is loaded top front in the case of mandatory image devices + if (warnings) + m_warnings.cpy(warnings); + else + m_warnings.reset(); } @@ -101,6 +108,12 @@ void ui_menu_file_manager::populate() bool first_entry = true; astring prev_owner; + if (m_warnings) + { + item_append(m_warnings, NULL, MENU_FLAG_DISABLE, NULL); + item_append("", NULL, MENU_FLAG_DISABLE, NULL); + } + // cycle through all devices for this system device_iterator iter(machine().root_device()); tagmap_t devtags; @@ -172,3 +185,22 @@ void ui_menu_file_manager::handle() } } } + +// force file manager menu +void ui_menu_file_manager::force_file_manager(running_machine &machine, render_container *container, const char *warnings) +{ + // reset the menu stack + ui_menu::stack_reset(machine); + + // add the quit entry followed by the game select entry + ui_menu *quit = auto_alloc_clear(machine, ui_menu_quit_game(machine, container)); + quit->set_special_main_menu(true); + ui_menu::stack_push(quit); + ui_menu::stack_push(auto_alloc_clear(machine, ui_menu_file_manager(machine, container, warnings))); + + // force the menus on + machine.ui().show_menu(); + + // make sure MAME is paused + machine.pause(); +} diff --git a/src/emu/ui/filemngr.h b/src/emu/ui/filemngr.h index 1e023477e10..3bcdb28679b 100644 --- a/src/emu/ui/filemngr.h +++ b/src/emu/ui/filemngr.h @@ -20,13 +20,18 @@ public: astring current_file; device_image_interface *selected_device; - ui_menu_file_manager(running_machine &machine, render_container *container); + static void force_file_manager(running_machine &machine, render_container *container, const char *warnings); + + ui_menu_file_manager(running_machine &machine, render_container *container, const char *warnings); virtual ~ui_menu_file_manager(); virtual void populate(); virtual void handle(); virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2); void fill_image_line(device_image_interface *img, astring &instance, astring &filename); + +private: + astring m_warnings; }; #endif /* __UI_FILEMNGR_H__ */ diff --git a/src/emu/ui/imgcntrl.c b/src/emu/ui/imgcntrl.c index 87d9add75f0..3405991977b 100644 --- a/src/emu/ui/imgcntrl.c +++ b/src/emu/ui/imgcntrl.c @@ -217,7 +217,6 @@ void ui_menu_control_device_image::handle() { swp = swi->first_part(); load_software_part(); - ui_menu::stack_pop(machine()); } break; @@ -225,7 +224,6 @@ void ui_menu_control_device_image::handle() switch(submenu_result) { case ui_menu_software_parts::T_ENTRY: { load_software_part(); - ui_menu::stack_pop(machine()); break; } diff --git a/src/emu/ui/mainmenu.c b/src/emu/ui/mainmenu.c index 90418814e21..418df62fee2 100644 --- a/src/emu/ui/mainmenu.c +++ b/src/emu/ui/mainmenu.c @@ -183,7 +183,7 @@ void ui_menu_main::handle() break; case IMAGE_MENU_FILE_MANAGER: - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_manager(machine(), container))); + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_manager(machine(), container, NULL))); break; case TAPE_CONTROL: diff --git a/src/emu/ui/selgame.c b/src/emu/ui/selgame.c index ac35d0b0dae..19e83a7dd54 100644 --- a/src/emu/ui/selgame.c +++ b/src/emu/ui/selgame.c @@ -157,7 +157,7 @@ void ui_menu_select_game::inkey_select(const ui_menu_event *menu_event) media_auditor::summary summary = auditor.audit_media(AUDIT_VALIDATE_FAST); // if everything looks good, schedule the new driver - if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE) + if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED) { machine().manager().schedule_new_driver(*driver); machine().schedule_hard_reset(); diff --git a/src/emu/ui/ui.c b/src/emu/ui/ui.c index 0d70c7e774a..125c66859fa 100644 --- a/src/emu/ui/ui.c +++ b/src/emu/ui/ui.c @@ -20,6 +20,7 @@ #include "uiinput.h" #include "ui/mainmenu.h" #include "ui/miscmenu.h" +#include "ui/filemngr.h" #include "ui/viewgfx.h" #include "imagedev/cassette.h" #include @@ -306,7 +307,7 @@ UINT32 ui_manager::set_handler(ui_callback callback, UINT32 param) void ui_manager::display_startup_screens(bool first_time, bool show_disclaimer) { - const int maxstate = 3; + const int maxstate = 4; int str = machine().options().seconds_to_run(); bool show_gameinfo = !machine().options().skip_gameinfo(); bool show_warnings = true; @@ -352,6 +353,15 @@ void ui_manager::display_startup_screens(bool first_time, bool show_disclaimer) if (show_gameinfo && game_info_astring(messagebox_text).len() > 0) set_handler(handler_messagebox_anykey, 0); break; + + case 3: + if (image_mandatory_scan(machine(), messagebox_text).len() > 0) + { + astring warning; + warning.cpy("This driver requires images to be loaded in the following device(s): ").cat(messagebox_text.substr(0, messagebox_text.len() - 2)); + ui_menu_file_manager::force_file_manager(machine(), &machine().render().ui_container(), warning.cstr()); + } + break; } // clear the input memory