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!
This commit is contained in:
etabeta78 2015-01-18 12:10:51 +01:00
parent 5c500d407b
commit 5bff739d72
8 changed files with 67 additions and 18 deletions

View File

@ -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;
}
/*-------------------------------------------------

View File

@ -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;

View File

@ -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<UINT8> 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();
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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:

View File

@ -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();

View File

@ -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 <ctype.h>
@ -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