diff options
-rw-r--r-- | src/emu/diimage.c | 304 | ||||
-rw-r--r-- | src/emu/diimage.h | 2 | ||||
-rw-r--r-- | src/emu/softlist.c | 64 | ||||
-rw-r--r-- | src/emu/softlist.h | 14 | ||||
-rw-r--r-- | src/emu/uiimage.c | 208 | ||||
-rw-r--r-- | src/emu/uiimage.h | 23 | ||||
-rw-r--r-- | src/emu/uiswlist.c | 172 | ||||
-rw-r--r-- | src/emu/uiswlist.h | 51 |
8 files changed, 513 insertions, 325 deletions
diff --git a/src/emu/diimage.c b/src/emu/diimage.c index e9d941e0fb6..fee67bceb2a 100644 --- a/src/emu/diimage.c +++ b/src/emu/diimage.c @@ -40,7 +40,9 @@ #include "emu.h" #include "ui.h" #include "zippath.h" - +#include "uimenu.h" +#include "uiimage.h" +#include "uiswlist.h" //************************************************************************** // DEVICE CONFIG IMAGE INTERFACE @@ -107,7 +109,7 @@ device_image_interface::~device_image_interface() //------------------------------------------------- // find_device_type - search trough list of -// device types to extact data +// device types to extract data //------------------------------------------------- const image_device_type_info *device_image_interface::find_device_type(iodevice_t type) @@ -1032,3 +1034,301 @@ void device_image_interface::update_names() m_brief_instance_name = device_brieftypename(image_type()); } } + +/*------------------------------------------------- + get_selection_menu - create the menu stack + for ui-level image selection +-------------------------------------------------*/ + +class ui_menu_control_device_image : public ui_menu { +public: + ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *image); + virtual ~ui_menu_control_device_image(); + virtual void populate(); + virtual void handle(); + +private: + enum { + START_FILE, START_OTHER_PART, START_SOFTLIST, SELECT_PARTLIST, SELECT_ONE_PART, SELECT_OTHER_PART, SELECT_FILE, CREATE_FILE, CREATE_CONFIRM, DO_CREATE, SELECT_SOFTLIST + }; + int state; + + device_image_interface *image; + astring current_directory; + astring current_file; + int submenu_result; + bool create_confirmed; + bool softlist_done; + const software_list *swl; + const software_info *swi; + const software_part *swp; + const software_list_config *slc; + astring software_info_name; + + void test_create(bool &can_create, bool &need_confirm); + void load_software_part(); +}; + +ui_menu *device_image_interface::get_selection_menu(running_machine &machine, render_container *container) +{ + return auto_alloc_clear(machine, ui_menu_control_device_image(machine, container, this)); +} + +ui_menu_control_device_image::ui_menu_control_device_image(running_machine &machine, render_container *container, device_image_interface *_image) : ui_menu(machine, container) +{ + image = _image; + + slc = 0; + swi = image->software_entry(); + swp = image->part_entry(); + + if(swi) + { + state = START_OTHER_PART; + current_directory.cpy(image->working_directory()); + } + else + { + state = START_FILE; + + /* if the image exists, set the working directory to the parent directory */ + if (image->exists()) + { + current_file.cpy(image->filename()); + zippath_parent(current_directory, current_file); + } else + current_directory.cpy(image->working_directory()); + + /* check to see if the path exists; if not clear it */ + if (zippath_opendir(current_directory, NULL) != FILERR_NONE) + current_directory.reset(); + } +} + +ui_menu_control_device_image::~ui_menu_control_device_image() +{ +} + + + + +/*------------------------------------------------- + create_new_image - creates a new disk image +-------------------------------------------------*/ + +void ui_menu_control_device_image::test_create(bool &can_create, bool &need_confirm) +{ + astring path; + osd_directory_entry *entry; + osd_dir_entry_type file_type; + + /* assemble the full path */ + zippath_combine(path, current_directory, current_file); + + /* does a file or a directory exist at the path */ + entry = osd_stat(path); + file_type = (entry != NULL) ? entry->type : ENTTYPE_NONE; + if (entry != NULL) + free(entry); + + switch(file_type) + { + case ENTTYPE_NONE: + /* no file/dir here - always create */ + can_create = true; + need_confirm = false; + break; + + case ENTTYPE_FILE: + /* a file exists here - ask for permission from the user */ + can_create = true; + need_confirm = true; + break; + + case ENTTYPE_DIR: + /* a directory exists here - we can't save over it */ + ui_popup_time(5, "Cannot save over directory"); + can_create = false; + need_confirm = false; + break; + + default: + fatalerror("Unexpected"); + can_create = false; + need_confirm = false; + break; + } +} + +void ui_menu_control_device_image::load_software_part() +{ + astring temp_name(swi->shortname); + temp_name.cat(":"); + temp_name.cat(swp->name); + image->load(temp_name.cstr()); +} + +void ui_menu_control_device_image::populate() +{ +} + +void ui_menu_control_device_image::handle() +{ + switch(state) { + case START_FILE: { + bool can_create = false; + if(image->is_creatable()) { + zippath_directory *directory = NULL; + file_error err = zippath_opendir(current_directory, &directory); + can_create = err == FILERR_NONE && !zippath_is_zip(directory); + if(directory) + zippath_closedir(directory); + } + submenu_result = -1; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_selector(machine(), container, image, current_directory, current_file, true, true, can_create, &submenu_result))); + state = SELECT_FILE; + break; + } + + case START_SOFTLIST: + slc = 0; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, image->image_interface(), &slc))); + state = SELECT_SOFTLIST; + break; + + case START_OTHER_PART: { + submenu_result = -1; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_parts(machine(), container, swi, swp->interface_, &swp, true, &submenu_result))); + state = SELECT_OTHER_PART; + break; + } + + case SELECT_SOFTLIST: + if(!slc) { + ui_menu::stack_pop(machine()); + break; + } + software_info_name = ""; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, slc, image->image_interface(), software_info_name))); + state = SELECT_PARTLIST; + break; + + case SELECT_PARTLIST: + swl = software_list_open(machine().options(), slc->list_name, false, NULL); + swi = software_list_find(swl, software_info_name, NULL); + if(swinfo_has_multiple_parts(swi, image->image_interface())) { + submenu_result = -1; + swp = 0; + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_parts(machine(), container, swi, image->image_interface(), &swp, false, &submenu_result))); + state = SELECT_ONE_PART; + } else { + image->load(software_info_name); + software_list_close(swl); + ui_menu::stack_pop(machine()); + } + break; + + case SELECT_ONE_PART: + switch(submenu_result) { + case ui_menu_software_parts::T_ENTRY: { + load_software_part(); + software_list_close(swl); + ui_menu::stack_pop(machine()); + break; + } + + case -1: // return to list + software_list_close(swl); + state = SELECT_SOFTLIST; + break; + + } + break; + + case SELECT_OTHER_PART: + switch(submenu_result) { + case ui_menu_software_parts::T_ENTRY: { + load_software_part(); + ui_menu::stack_pop(machine()); + break; + } + + case ui_menu_software_parts::T_FMGR: + state = START_FILE; + handle(); + break; + + case -1: // return to system + ui_menu::stack_pop(machine()); + break; + + } + break; + + case SELECT_FILE: + switch(submenu_result) { + case ui_menu_file_selector::R_EMPTY: + image->unload(); + ui_menu::stack_pop(machine()); + break; + + case ui_menu_file_selector::R_FILE: + image->load(current_file); + ui_menu::stack_pop(machine()); + break; + + case ui_menu_file_selector::R_CREATE: + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_create(machine(), container, image, current_directory, current_file))); + state = CREATE_FILE; + break; + + case ui_menu_file_selector::R_SOFTLIST: + state = START_SOFTLIST; + handle(); + break; + + case -1: // return to system + ui_menu::stack_pop(machine()); + break; + } + break; + + case CREATE_FILE: { + bool can_create, need_confirm; + test_create(can_create, need_confirm); + if(can_create) { + if(need_confirm) { + ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_confirm_save_as(machine(), container, &create_confirmed))); + state = CREATE_CONFIRM; + } else { + astring path; + zippath_combine(path, current_directory, current_file); + int err = image->create(path, 0, NULL); + if (err != 0) + popmessage("Error: %s", image->error()); + ui_menu::stack_pop(machine()); + } + } else { + state = START_FILE; + handle(); + } + break; + } + + case CREATE_CONFIRM: { + state = create_confirmed ? DO_CREATE : START_FILE; + handle(); + break; + } + + case DO_CREATE: { + astring path; + zippath_combine(path, current_directory, current_file); + int err = image->create(path, 0, NULL); + if (err != 0) + popmessage("Error: %s", image->error()); + ui_menu::stack_pop(machine()); + break; + } + } +} diff --git a/src/emu/diimage.h b/src/emu/diimage.h index 5311e1703aa..f07cf88977d 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -182,6 +182,8 @@ public: virtual const char *file_extensions() const = 0; virtual const option_guide *create_option_guide() const = 0; + virtual class ui_menu *get_selection_menu(running_machine &machine, class render_container *container); + const image_device_format *device_get_indexed_creatable_format(int index); const image_device_format *device_get_named_creatable_format(const char *format_name); const option_guide *device_get_creation_option_guide() { return create_option_guide(); } diff --git a/src/emu/softlist.c b/src/emu/softlist.c index fdcd4a5edad..df6b66e80b3 100644 --- a/src/emu/softlist.c +++ b/src/emu/softlist.c @@ -975,11 +975,11 @@ static void data_handler(void *data, const XML_Char *s, int len) software_list_get_count -------------------------------------------------*/ -static int software_list_get_count(software_list *swlist) +static int software_list_get_count(const software_list *swlist) { int count = 0; - for (software_info *swinfo = software_list_find(swlist, "*", NULL); swinfo != NULL; swinfo = software_list_find(swlist, "*", swinfo)) + for (const software_info *swinfo = software_list_find(swlist, "*", NULL); swinfo != NULL; swinfo = software_list_find(swlist, "*", swinfo)) count++; return count; @@ -993,11 +993,11 @@ static int software_list_get_count(software_list *swlist) const char *software_get_clone(emu_options &options, char *swlist, const char *swname) { - software_list *software_list_ptr = software_list_open(options, swlist, FALSE, NULL); + const software_list *software_list_ptr = software_list_open(options, swlist, FALSE, NULL); const char *retval = NULL; if (software_list_ptr) { - software_info *tmp = software_list_find(software_list_ptr, swname, NULL); + const software_info *tmp = software_list_find(software_list_ptr, swname, NULL); retval = core_strdup(tmp->parentname); software_list_close(software_list_ptr); } @@ -1013,12 +1013,12 @@ const char *software_get_clone(emu_options &options, char *swlist, const char *s UINT32 software_get_support(emu_options &options, char *swlist, const char *swname) { - software_list *software_list_ptr = software_list_open(options, swlist, FALSE, NULL); + const software_list *software_list_ptr = software_list_open(options, swlist, FALSE, NULL); UINT32 retval = 0; if (software_list_ptr) { - software_info *tmp = software_list_find(software_list_ptr, swname, NULL); + const software_info *tmp = software_list_find(software_list_ptr, swname, NULL); retval = tmp->supported; software_list_close(software_list_ptr); } @@ -1132,7 +1132,7 @@ error: software_list_close -------------------------------------------------*/ -void software_list_close(software_list *swlist) +void software_list_close(const software_list *swlist) { if (swlist == NULL) return; @@ -1147,7 +1147,7 @@ void software_list_close(software_list *swlist) software_list_get_description -------------------------------------------------*/ -const char *software_list_get_description(software_list *swlist) +const char *software_list_get_description(const software_list *swlist) { return swlist->description; } @@ -1279,7 +1279,7 @@ void software_list_find_approx_matches(software_list_config *swlistcfg, software software_list_find -------------------------------------------------*/ -software_info *software_list_find(software_list *swlist, const char *look_for, software_info *prev) +const software_info *software_list_find(const software_list *swlist, const char *look_for, const software_info *prev) { if (swlist == NULL) return NULL; @@ -1288,8 +1288,9 @@ software_info *software_list_find(software_list *swlist, const char *look_for, s return NULL; /* If we haven't read in the xml file yet, then do it now */ + /* Just-in-time parsing, hence the const-cast */ if ( ! swlist->software_info_list ) - software_list_parse( swlist, swlist->error_proc, NULL ); + software_list_parse( const_cast<software_list *>(swlist), swlist->error_proc, NULL ); for ( prev = prev ? prev->next : swlist->software_info_list; prev; prev = prev->next ) { @@ -1300,6 +1301,12 @@ software_info *software_list_find(software_list *swlist, const char *look_for, s return prev; } +software_info *software_list_find(software_list *swlist, const char *look_for, software_info *prev) +{ + return const_cast<software_info *>(software_list_find(const_cast<const software_list *>(swlist), + look_for, + const_cast<const software_info *>(prev))); +} /*------------------------------------------------- software_find_romdata (for validation purposes) @@ -1357,9 +1364,9 @@ static struct rom_entry *software_romdata_next(struct rom_entry *romdata) software_find_part -------------------------------------------------*/ -software_part *software_find_part(software_info *sw, const char *partname, const char *interface) +const software_part *software_find_part(const software_info *sw, const char *partname, const char *interface) { - software_part *part = sw ? sw->partdata : NULL; + const software_part *part = sw ? sw->partdata : NULL; /* If neither partname nor interface supplied, then we just return the first entry */ if ( partname || interface ) @@ -1404,12 +1411,16 @@ software_part *software_find_part(software_info *sw, const char *partname, const return part; } +software_part *software_find_part(software_info *sw, const char *partname, const char *interface) +{ + return const_cast<software_part *>(software_find_part(const_cast<const software_info *>(sw), partname, interface)); +} /*------------------------------------------------- software_part_next -------------------------------------------------*/ -software_part *software_part_next(software_part *part) +const software_part *software_part_next(const software_part *part) { if ( part && part->name ) { @@ -1422,6 +1433,11 @@ software_part *software_part_next(software_part *part) return part; } +software_part *software_part_next(software_part *part) +{ + return const_cast<software_part *>(software_part_next(const_cast<const software_part *>(part))); +} + /*------------------------------------------------- software_display_matches -------------------------------------------------*/ @@ -1754,9 +1770,9 @@ bool load_software_part(emu_options &options, device_image_interface *image, con software_part_get_feature -------------------------------------------------*/ -const char *software_part_get_feature(software_part *part, const char *feature_name) +const char *software_part_get_feature(const software_part *part, const char *feature_name) { - feature_list *feature; + const feature_list *feature; if (part == NULL) return NULL; @@ -1803,7 +1819,7 @@ const char *software_part_get_feature(software_part *part, const char *feature_n is_software_compatible -------------------------------------------------*/ -bool is_software_compatible(software_part *swpart, software_list_config *swlist) +bool is_software_compatible(const software_part *swpart, const software_list_config *swlist) { const char *compatibility = software_part_get_feature(swpart, "compatibility"); const char *filter = swlist->filter; @@ -1819,6 +1835,22 @@ bool is_software_compatible(software_part *swpart, software_list_config *swlist) return FALSE; } +/*------------------------------------------------- + swinfo_has_multiple_parts + -------------------------------------------------*/ + +bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interface) +{ + int count = 0; + + for (const software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) + { + if (strcmp(interface, swpart->interface_) == 0) + count++; + } + return (count > 1) ? true : false; +} + /*************************************************************************** DEVICE INTERFACE ***************************************************************************/ diff --git a/src/emu/softlist.h b/src/emu/softlist.h index 37bb48b07d5..9748342b334 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -107,18 +107,22 @@ struct _software_list_config /* Handling a software list */ software_list *software_list_open(emu_options &options, const char *listname, int is_preload, void (*error_proc)(const char *message)); -void software_list_close(software_list *swlist); +void software_list_close(const software_list *swlist); software_info *software_list_find(software_list *swlist, const char *look_for, software_info *prev); -const char *software_list_get_description(software_list *swlist); +const char *software_list_get_description(const software_list *swlist); void software_list_parse(software_list *swlist, void (*error_proc)(const char *message), void *param); software_part *software_find_part(software_info *sw, const char *partname, const char *interface_); software_part *software_part_next(software_part *part); +const software_info *software_list_find(const software_list *swlist, const char *look_for, const software_info *prev); +const software_part *software_find_part(const software_info *sw, const char *partname, const char *interface_); +const software_part *software_part_next(const software_part *part); + /* helpers */ const char *software_get_clone(emu_options &options, char *swlist, const char *swname); UINT32 software_get_support(emu_options &options, char *swlist, const char *swname); -const char *software_part_get_feature(software_part *part, const char *feature_name); +const char *software_part_get_feature(const software_part *part, const char *feature_name); bool load_software_part(emu_options &options, device_image_interface *image, const char *path, software_info **sw_info, software_part **sw_part, char **full_sw_name); @@ -128,7 +132,9 @@ const char *software_get_default_slot(const device_list &devlist, emu_options &o void validate_softlists(emu_options &options); -bool is_software_compatible(software_part *swpart, software_list_config *swlist); +bool is_software_compatible(const software_part *swpart, const software_list_config *swlist); +bool swinfo_has_multiple_parts(const software_info *swinfo, const char *interface); + /********************************************************************* Driver software list configuration diff --git a/src/emu/uiimage.c b/src/emu/uiimage.c index c36c6c98071..56449a43f72 100644 --- a/src/emu/uiimage.c +++ b/src/emu/uiimage.c @@ -149,9 +149,10 @@ static void extra_text_render(render_container *container, float top, float bott confirm save as menu -------------------------------------------------*/ -ui_menu_confirm_save_as::ui_menu_confirm_save_as(running_machine &machine, render_container *container, int *_yes) : ui_menu(machine, container) +ui_menu_confirm_save_as::ui_menu_confirm_save_as(running_machine &machine, render_container *container, bool *_yes) : ui_menu(machine, container) { yes = _yes; + *yes = false; } ui_menu_confirm_save_as::~ui_menu_confirm_save_as() @@ -160,7 +161,7 @@ ui_menu_confirm_save_as::~ui_menu_confirm_save_as() void ui_menu_confirm_save_as::populate() { - item_append("File Already Exists - Overide?", NULL, MENU_FLAG_DISABLE, NULL); + item_append("File Already Exists - Override?", NULL, MENU_FLAG_DISABLE, NULL); item_append(MENU_SEPARATOR_ITEM, NULL, MENU_FLAG_DISABLE, NULL); item_append("No", NULL, 0, ITEMREF_NO); item_append("Yes", NULL, 0, ITEMREF_YES); @@ -179,7 +180,7 @@ void ui_menu_confirm_save_as::handle() if ((event != NULL) && (event->iptkey == IPT_UI_SELECT)) { if (event->itemref == ITEMREF_YES) - *yes = TRUE; + *yes = true; /* no matter what, pop out */ ui_menu::stack_pop(machine()); @@ -224,7 +225,7 @@ static int is_valid_filename_char(unicode_char unichar) void ui_menu_file_create::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) { extra_text_render(container, top, bottom, origx1, origy1, origx2, origy2, - manager->current_directory, + current_directory, NULL); } @@ -235,9 +236,9 @@ void ui_menu_file_create::custom_render(void *selectedref, float top, float bott creator menu -------------------------------------------------*/ -ui_menu_file_create::ui_menu_file_create(running_machine &machine, render_container *container, ui_menu_file_manager *parent) : ui_menu(machine, container) +ui_menu_file_create::ui_menu_file_create(running_machine &machine, render_container *container, device_image_interface *_image, astring &_current_directory, astring &_current_file) : ui_menu(machine, container), current_directory(_current_directory), current_file(_current_file) { - manager = parent; + image = _image; } ui_menu_file_create::~ui_menu_file_create() @@ -247,7 +248,6 @@ ui_menu_file_create::~ui_menu_file_create() void ui_menu_file_create::populate() { astring buffer; - device_image_interface *device = manager->selected_device; const image_device_format *format; const char *new_image_name; @@ -264,7 +264,7 @@ void ui_menu_file_create::populate() item_append("New Image Name:", new_image_name, 0, ITEMREF_NEW_IMAGE_NAME); /* do we support multiple formats? */ - format = device->device_get_creatable_formats(); + format = image->device_get_creatable_formats(); if (ENABLE_FORMATS && (format != NULL)) { item_append("Image Format:", current_format->m_description, 0, ITEMREF_FORMAT); @@ -279,94 +279,14 @@ void ui_menu_file_create::populate() } - -/*------------------------------------------------- - create_new_image - creates a new disk image --------------------------------------------------*/ - -int ui_menu_file_create::create_new_image(device_image_interface *image, const char *directory, const char *filename, int *yes) -{ - astring path; - osd_directory_entry *entry; - osd_dir_entry_type file_type; - int do_create, err; - int result = FALSE; - - /* assemble the full path */ - zippath_combine(path, directory, filename); - - /* does a file or a directory exist at the path */ - entry = osd_stat(path); - file_type = (entry != NULL) ? entry->type : ENTTYPE_NONE; - if (entry != NULL) - free(entry); - - /* special case */ - if ((file_type == ENTTYPE_FILE) && *yes) - file_type = ENTTYPE_NONE; - - switch(file_type) - { - case ENTTYPE_NONE: - /* no file/dir here - always create */ - do_create = TRUE; - break; - - case ENTTYPE_FILE: - /* a file exists here - ask for permission from the user */ - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_confirm_save_as(machine(), container, yes))); - do_create = FALSE; - break; - - case ENTTYPE_DIR: - /* a directory exists here - we can't save over it */ - ui_popup_time(ERROR_MESSAGE_TIME, "Cannot save over directory"); - do_create = FALSE; - break; - - default: - fatalerror("Unexpected"); - do_create = FALSE; - break; - } - - /* create the image, if appropriate */ - if (do_create) - { - err = image->create(path, 0, NULL); - if (err != 0) - popmessage("Error: %s", image->error()); - else - result = TRUE; - } - - return result; -} - - - /*------------------------------------------------- menu_file_create - file creator menu -------------------------------------------------*/ void ui_menu_file_create::handle() { - const ui_menu_event *event; - ui_menu_event fake_event; - - if (confirm_save_as_yes) - { - /* we just returned from a "confirm save as" dialog and the user said "yes" - fake an event */ - memset(&fake_event, 0, sizeof(fake_event)); - fake_event.iptkey = IPT_UI_SELECT; - fake_event.itemref = ITEMREF_CREATE; - event = &fake_event; - } - else - { - /* process the menu */ - event = process(0); - } + /* process the menu */ + const ui_menu_event *event = process(0); /* process the event */ if (event != NULL) @@ -377,16 +297,8 @@ void ui_menu_file_create::handle() case IPT_UI_SELECT: if ((event->itemref == ITEMREF_CREATE) || (event->itemref == ITEMREF_NEW_IMAGE_NAME)) { - if (create_new_image( - manager->selected_device, - manager->current_directory, - filename_buffer, - &confirm_save_as_yes)) - { - /* success - pop out twice to device view */ - ui_menu::stack_pop(machine()); - ui_menu::stack_pop(machine()); - } + current_file.cpy(filename_buffer); + ui_menu::stack_pop(machine()); } break; @@ -398,6 +310,7 @@ void ui_menu_file_create::handle() ARRAY_LENGTH(filename_buffer), event->unichar, is_valid_filename_char); + reset(UI_MENU_RESET_REMEMBER_POSITION); } break; } @@ -419,7 +332,7 @@ void ui_menu_file_selector::custom_render(void *selectedref, float top, float bo { extra_text_render(container, top, bottom, origx1, origy1, origx2, origy2, - manager->current_directory, + current_directory, NULL); } @@ -523,10 +436,7 @@ ui_menu_file_selector::file_selector_entry *ui_menu_file_selector::append_dirent } /* determine the full path */ - zippath_combine( - buffer, - manager->current_directory, - dirent->name); + zippath_combine(buffer, current_directory, dirent->name); /* create the file selector entry */ entry = append_entry( @@ -587,9 +497,13 @@ void ui_menu_file_selector::append_entry_menu_item(const file_selector_entry *en allocates all menu items for a directory -------------------------------------------------*/ -ui_menu_file_selector::ui_menu_file_selector(running_machine &machine, render_container *container, ui_menu_file_manager *parent) : ui_menu(machine, container) +ui_menu_file_selector::ui_menu_file_selector(running_machine &machine, render_container *container, device_image_interface *_image, astring &_current_directory, astring &_current_file, bool _has_empty, bool _has_softlist, bool _has_create, int *_result) : ui_menu(machine, container), current_directory(_current_directory), current_file(_current_file) { - manager = parent; + image = _image; + has_empty = _has_empty; + has_softlist = _has_softlist; + has_create = _has_create; + result = _result; } ui_menu_file_selector::~ui_menu_file_selector() @@ -605,8 +519,10 @@ void ui_menu_file_selector::populate() const file_selector_entry *selected_entry = NULL; int i; const char *volume_name; - device_image_interface *device = manager->selected_device; - const char *path = manager->current_directory; + const char *path = current_directory; + + if(path[0]) + fprintf(stderr, "curdir=%s\n", path); /* open the directory */ err = zippath_opendir(path, &directory); @@ -616,17 +532,21 @@ void ui_menu_file_selector::populate() /* clear out the menu entries */ entrylist = NULL; - /* add the "[empty slot]" entry */ - append_entry(SELECTOR_ENTRY_TYPE_EMPTY, NULL, NULL); + if (has_empty) + { + /* add the "[empty slot]" entry */ + append_entry(SELECTOR_ENTRY_TYPE_EMPTY, NULL, NULL); + } - if (device->is_creatable() && !zippath_is_zip(directory)) + if (has_create) { /* add the "[create]" entry */ append_entry(SELECTOR_ENTRY_TYPE_CREATE, NULL, NULL); } - /* add the "[software list]" entry */ - append_entry(SELECTOR_ENTRY_TYPE_SOFTWARE_LIST, NULL, NULL); + if (has_softlist) + /* add the "[software list]" entry */ + append_entry(SELECTOR_ENTRY_TYPE_SOFTWARE_LIST, NULL, NULL); /* add the drives */ i = 0; @@ -650,7 +570,7 @@ void ui_menu_file_selector::populate() selected_entry = entry; /* do we have to select this file? */ - if (!mame_stricmp(manager->current_file, dirent->name)) + if (!mame_stricmp(current_file, dirent->name)) selected_entry = entry; } } @@ -671,17 +591,6 @@ done: zippath_closedir(directory); } -/*------------------------------------------------- - check_path - performs a quick check to see if - a path exists --------------------------------------------------*/ - -static file_error check_path(const char *path) -{ - return zippath_opendir(path, NULL); -} - - /*------------------------------------------------- menu_file_selector - file selector menu @@ -706,34 +615,37 @@ void ui_menu_file_selector::handle() { case SELECTOR_ENTRY_TYPE_EMPTY: /* empty slot - unload */ - manager->selected_device->unload(); + *result = R_EMPTY; ui_menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_CREATE: /* create */ - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_create(machine(), container, manager))); + *result = R_CREATE; + ui_menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST: - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software(machine(), container, manager->selected_device))); + *result = R_SOFTLIST; + ui_menu::stack_pop(machine()); break; case SELECTOR_ENTRY_TYPE_DRIVE: case SELECTOR_ENTRY_TYPE_DIRECTORY: /* drive/directory - first check the path */ - err = check_path(entry->fullpath); + err = zippath_opendir(entry->fullpath, NULL); if (err != FILERR_NONE) { /* this path is problematic; present the user with an error and bail */ ui_popup_time(1, "Error accessing %s", entry->fullpath); break; } - manager->current_directory.cpy(entry->fullpath); + current_directory.cpy(entry->fullpath); reset((ui_menu_reset_options)0); break; case SELECTOR_ENTRY_TYPE_FILE: /* file */ - manager->selected_device->load(entry->fullpath); + current_file.cpy(entry->fullpath); + *result = R_FILE; ui_menu::stack_pop(machine()); break; } @@ -830,28 +742,6 @@ void ui_menu_file_selector::handle() FILE MANAGER ***************************************************************************/ -/*------------------------------------------------- - fix_working_directory - checks the working - directory for this device to ensure that it - "makes sense" --------------------------------------------------*/ - -void ui_menu_file_manager::fix_working_directory(device_image_interface *image) -{ - /* if the image exists, set the working directory to the parent directory */ - if (image->exists()) - { - astring astr; - zippath_parent(astr, image->filename()); - image->set_working_directory(astr); - } - - /* check to see if the path exists; if not clear it */ - if (check_path(image->working_directory()) != FILERR_NONE) - image->set_working_directory(""); -} - - /*------------------------------------------------- file_manager_render_extra - perform our @@ -954,18 +844,10 @@ void ui_menu_file_manager::handle() selected_device = (device_image_interface *) event->itemref; if (selected_device != NULL) { - /* ensure that the working directory for this device exists */ - fix_working_directory(selected_device); - - /* set up current_directory and current_file - depends on whether we have an image */ - current_directory.cpy(selected_device->working_directory()); - current_file.cpy(selected_device->exists() ? selected_device->basename() : ""); + ui_menu::stack_push(selected_device->get_selection_menu(machine(), container)); /* reset the existing menu */ reset(UI_MENU_RESET_REMEMBER_POSITION); - - /* push the menu */ - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_file_selector(machine(), container, this))); } } } diff --git a/src/emu/uiimage.h b/src/emu/uiimage.h index aaf11b101ff..5dd80618cd1 100644 --- a/src/emu/uiimage.h +++ b/src/emu/uiimage.h @@ -33,9 +33,6 @@ public: virtual void populate(); virtual void handle(); virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2); - -private: - void fix_working_directory(device_image_interface *image); }; class ui_menu_mess_tape_control : public ui_menu { @@ -66,35 +63,35 @@ private: class ui_menu_confirm_save_as : public ui_menu { public: - ui_menu_confirm_save_as(running_machine &machine, render_container *container, int *yes); + ui_menu_confirm_save_as(running_machine &machine, render_container *container, bool *yes); virtual ~ui_menu_confirm_save_as(); virtual void populate(); virtual void handle(); private: - int *yes; + bool *yes; }; class ui_menu_file_create : public ui_menu { public: - ui_menu_file_create(running_machine &machine, render_container *container, ui_menu_file_manager *parent); + ui_menu_file_create(running_machine &machine, render_container *container, device_image_interface *image, astring ¤t_directory, astring ¤t_file); virtual ~ui_menu_file_create(); virtual void populate(); virtual void handle(); virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2); private: - ui_menu_file_manager *manager; + device_image_interface *image; + astring ¤t_directory, ¤t_file; const image_device_format *current_format; int confirm_save_as_yes; char filename_buffer[1024]; - - int create_new_image(device_image_interface *image, const char *directory, const char *filename, int *yes); }; class ui_menu_file_selector : public ui_menu { public: - ui_menu_file_selector(running_machine &machine, render_container *container, ui_menu_file_manager *parent); + enum { R_EMPTY, R_SOFTLIST, R_CREATE, R_FILE }; + ui_menu_file_selector(running_machine &machine, render_container *container, device_image_interface *image, astring ¤t_directory, astring ¤t_file, bool has_empty, bool has_softlist, bool has_create, int *result); virtual ~ui_menu_file_selector(); virtual void populate(); virtual void handle(); @@ -118,7 +115,11 @@ private: const char *fullpath; }; - ui_menu_file_manager *manager; + device_image_interface *image; + astring ¤t_directory, ¤t_file; + bool has_empty, has_softlist, has_create; + int *result; + file_selector_entry *entrylist; char filename_buffer[1024]; diff --git a/src/emu/uiswlist.c b/src/emu/uiswlist.c index d0659143c96..011e416059e 100644 --- a/src/emu/uiswlist.c +++ b/src/emu/uiswlist.c @@ -28,46 +28,42 @@ TYPE DEFINITIONS ***************************************************************************/ -ui_menu_software_parts::ui_menu_software_parts(running_machine &machine, render_container *container, ui_menu_software_entry_info *_entry) : ui_menu(machine, container) +ui_menu_software_parts::ui_menu_software_parts(running_machine &machine, render_container *container, const software_info *_info, const char *_interface, const software_part **part, bool _opt_fmgr, int *_result) : ui_menu(machine, container) { - entry = _entry; + info = _info; + interface = _interface; + selected_part = part; + opt_fmgr = _opt_fmgr; + result = _result; } void ui_menu_software_parts::populate() { - if(entry->list_name) { - software_list *list = software_list_open(machine().options(), entry->list_name, false, NULL); - - if (list) + for (const software_part *swpart = software_find_part(info, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) + { + if (strcmp(interface, swpart->interface_) == 0) { - software_info *info = software_list_find(list, entry->short_name, NULL); - - if (info) + software_part_menu_entry *entry = (software_part_menu_entry *) m_pool_alloc(sizeof(*entry)); + // check if the available parts have specific part_id to be displayed (e.g. "Map Disc", "Bonus Disc", etc.) + // if not, we simply display "part_name"; if yes we display "part_name (part_id)" + astring menu_part_name(swpart->name); + if (software_part_get_feature(swpart, "part_id") != NULL) { - for (software_part *swpart = software_find_part(info, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) - { - if (strcmp(entry->interface, swpart->interface_) == 0) - { - software_part_info *entry = (software_part_info *) m_pool_alloc(sizeof(*entry)); - // check if the available parts have specific part_id to be displayed (e.g. "Map Disc", "Bonus Disc", etc.) - // if not, we simply display "part_name"; if yes we display "part_name (part_id)" - astring menu_part_name(swpart->name); - if (software_part_get_feature(swpart, "part_id") != NULL) - { - menu_part_name.cat(" ("); - menu_part_name.cat(software_part_get_feature(swpart, "part_id")); - menu_part_name.cat(")"); - } - entry->part_name = pool_strdup(swpart->name); // part_name is later used to build up the filename to load, so we use swpart->name! - entry->interface = pool_strdup(swpart->interface_); - item_append(info->shortname, menu_part_name.cstr(), 0, entry); - } - } + menu_part_name.cat(" ("); + menu_part_name.cat(software_part_get_feature(swpart, "part_id")); + menu_part_name.cat(")"); } - - software_list_close(list); + entry->type = T_ENTRY; + entry->part = swpart; + item_append(info->shortname, menu_part_name.cstr(), 0, entry); } } + if(opt_fmgr) { + software_part_menu_entry *entry = (software_part_menu_entry *) m_pool_alloc(sizeof(*entry)); + entry->type = T_FMGR; + entry->part = 0; + item_append("[file manager]", 0, 0, entry); + } } ui_menu_software_parts::~ui_menu_software_parts() @@ -81,19 +77,14 @@ void ui_menu_software_parts::handle() if (event != NULL && event->iptkey == IPT_UI_SELECT && event->itemref != NULL) { - software_part_info *pentry = (software_part_info *) event->itemref; - - // build the name for the part to be loaded - astring temp_name(entry->short_name); - temp_name.cat(":"); - temp_name.cat(pentry->part_name); - //printf("%s\n", temp_name.cstr()); - - entry->image->load(temp_name.cstr()); + software_part_menu_entry *entry = (software_part_menu_entry *) event->itemref; + *result = entry->type; + *selected_part = entry->part; + ui_menu::stack_pop(machine()); } } -int ui_menu_software_list::compare_entries(const ui_menu_software_entry_info *e1, const ui_menu_software_entry_info *e2, bool shortname) +int ui_menu_software_list::compare_entries(const entry_info *e1, const entry_info *e2, bool shortname) { int result; const char *e1_basename; @@ -128,28 +119,24 @@ int ui_menu_software_list::compare_entries(const ui_menu_software_entry_info *e1 /* populate a specific list */ -ui_menu_software_entry_info *ui_menu_software_list::append_software_entry(software_info *swinfo, device_image_interface* image) +ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(const software_info *swinfo) { - ui_menu_software_entry_info *entry = NULL; - ui_menu_software_entry_info **entryptr; - const char *interface = image->image_interface(); + entry_info *entry = NULL; + entry_info **entryptr; bool entry_updated = FALSE; // check if at least one of the parts has the correct interface and add a menu entry only in this case - for (software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) + for (const software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) { if ((strcmp(interface, swpart->interface_) == 0) && is_software_compatible(swpart, swlist)) { entry_updated = TRUE; // allocate a new entry - entry = (ui_menu_software_entry_info *) m_pool_alloc(sizeof(*entry)); + entry = (entry_info *) m_pool_alloc(sizeof(*entry)); memset(entry, 0, sizeof(*entry)); entry->short_name = pool_strdup(swinfo->shortname); entry->long_name = pool_strdup(swinfo->longname); - entry->list_name = swlist->list_name; - entry->image = image; - entry->interface = pool_strdup(swpart->interface_); break; } } @@ -170,10 +157,10 @@ ui_menu_software_entry_info *ui_menu_software_list::append_software_entry(softwa return entry; } -ui_menu_software_list::ui_menu_software_list(running_machine &machine, render_container *container, software_list_config *_swlist, device_image_interface *_image) : ui_menu(machine, container) +ui_menu_software_list::ui_menu_software_list(running_machine &machine, render_container *container, const software_list_config *_swlist, const char *_interface, astring &_result) : ui_menu(machine, container), result(_result) { swlist = _swlist; - image = _image; + interface = _interface; entrylist = NULL; ordered_by_shortname = true; } @@ -184,13 +171,13 @@ ui_menu_software_list::~ui_menu_software_list() void ui_menu_software_list::populate() { - software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); + const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); // build up the list of entries for the menu if (list) { - for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) - append_software_entry(swinfo, image); + for (const software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) + append_software_entry(swinfo); software_list_close(list); } @@ -199,26 +186,14 @@ void ui_menu_software_list::populate() item_append("Switch Item Ordering", NULL, 0, (void *)1); // append all of the menu entries - for (ui_menu_software_entry_info *entry = entrylist; entry != NULL; entry = entry->next) + for (entry_info *entry = entrylist; entry != NULL; entry = entry->next) item_append(entry->short_name, entry->long_name, 0, entry); } -bool ui_menu_software_list::swinfo_has_multiple_parts(software_info *swinfo, const char *interface) -{ - int count = 0; - - for (software_part *swpart = software_find_part(swinfo, NULL, NULL); swpart != NULL; swpart = software_part_next(swpart)) - { - if (strcmp(interface, swpart->interface_) == 0) - count++; - } - return (count > 1) ? true : false; -} - void ui_menu_software_list::handle() { - const ui_menu_software_entry_info *entry; - const ui_menu_software_entry_info *selected_entry = NULL; + const entry_info *entry; + const entry_info *selected_entry = NULL; int bestmatch = 0; /* process the menu */ @@ -240,25 +215,9 @@ void ui_menu_software_list::handle() /* handle selections */ else if (event->iptkey == IPT_UI_SELECT) { - ui_menu_software_entry_info *entry = (ui_menu_software_entry_info *) event->itemref; - software_list *tmp_list = software_list_open(machine().options(), swlist->list_name, false, NULL); - software_info *tmp_info = software_list_find(tmp_list, entry->short_name, NULL); - - // if the selected software has multiple parts that can be loaded, open the submenu - if (swinfo_has_multiple_parts(tmp_info, image->image_interface())) - { - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_parts(machine(), container, entry))); - } - else - { - // otherwise, load the file - image->load(entry->short_name); - } - software_list_close(tmp_list); - - // reset the char buffer when pressing IPT_UI_SELECT - if (filename_buffer[0] != '\0') - memset(filename_buffer, '\0', ARRAY_LENGTH(filename_buffer)); + entry_info *entry = (entry_info *) event->itemref; + result = entry->short_name; + ui_menu::stack_pop(machine()); } else if (event->iptkey == IPT_SPECIAL) { @@ -287,11 +246,11 @@ void ui_menu_software_list::handle() if (update_selected) { - const ui_menu_software_entry_info *cur_selected; + const entry_info *cur_selected; // if the current selection is a software entry, start search from here if ((FPTR)event->itemref != 1) - cur_selected= (const ui_menu_software_entry_info *)get_selection(); + cur_selected= (const entry_info *)get_selection(); // else (if we are on the 'Switch Order' entry) start from the beginning else cur_selected= entrylist; @@ -354,37 +313,37 @@ void ui_menu_software_list::handle() } /* list of available software lists - i.e. cartridges, floppies */ -ui_menu_software::ui_menu_software(running_machine &machine, render_container *container, device_image_interface* _image) : ui_menu(machine, container) +ui_menu_software::ui_menu_software(running_machine &machine, render_container *container, const char *_interface, const software_list_config **_result) : ui_menu(machine, container) { - image = _image; + interface = _interface; + result = _result; } void ui_menu_software::populate() { bool haveCompatible = false; - const char *interface = image->image_interface(); // Add original software lists for this system for (const device_t *dev = machine().config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); + const software_list_config *swlist = (const software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); if (swlist->list_type == SOFTWARE_LIST_ORIGINAL_SYSTEM) { - software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); + const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); if (list) { bool found = false; - for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) + for (const software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) { - software_part *part = software_find_part(swinfo, NULL, NULL); + const software_part *part = software_find_part(swinfo, NULL, NULL); if (strcmp(interface,part->interface_)==0) { found = true; } } if (found) { - item_append(list->description, NULL, 0, swlist); + item_append(list->description, NULL, 0, (void *)swlist); } software_list_close(list); @@ -395,18 +354,18 @@ void ui_menu_software::populate() // Add compatible software lists for this system for (const device_t *dev = machine().config().devicelist().first(SOFTWARE_LIST); dev != NULL; dev = dev->typenext()) { - software_list_config *swlist = (software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); + const software_list_config *swlist = (const software_list_config *)downcast<const legacy_device_base *>(dev)->inline_config(); if (swlist->list_type == SOFTWARE_LIST_COMPATIBLE_SYSTEM) { - software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); + const software_list *list = software_list_open(machine().options(), swlist->list_name, false, NULL); if (list) { bool found = false; - for (software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) + for (const software_info *swinfo = software_list_find(list, "*", NULL); swinfo != NULL; swinfo = software_list_find(list, "*", swinfo)) { - software_part *part = software_find_part(swinfo, NULL, NULL); + const software_part *part = software_find_part(swinfo, NULL, NULL); if (strcmp(interface,part->interface_)==0) { found = true; } @@ -415,7 +374,7 @@ void ui_menu_software::populate() if (!haveCompatible) { item_append("[compatible lists]", NULL, MENU_FLAG_DISABLE, NULL); } - item_append(list->description, NULL, 0, swlist); + item_append(list->description, NULL, 0, (void *)swlist); } haveCompatible = true; @@ -435,6 +394,9 @@ void ui_menu_software::handle() /* process the menu */ const ui_menu_event *event = process(0); - if (event != NULL && event->iptkey == IPT_UI_SELECT) - ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, (software_list_config *)event->itemref, image))); + if (event != NULL && event->iptkey == IPT_UI_SELECT) { + // ui_menu::stack_push(auto_alloc_clear(machine(), ui_menu_software_list(machine(), container, (software_list_config *)event->itemref, image))); + *result = (software_list_config *)event->itemref; + ui_menu::stack_pop(machine()); + } } diff --git a/src/emu/uiswlist.h b/src/emu/uiswlist.h index ad57fc279c8..da92c9f5917 100644 --- a/src/emu/uiswlist.h +++ b/src/emu/uiswlist.h @@ -12,60 +12,63 @@ #ifndef __UISWLIST_H__ #define __UISWLIST_H__ -struct ui_menu_software_entry_info { - ui_menu_software_entry_info *next; - - const char *short_name; - const char *long_name; - const char *interface; - char *list_name; - device_image_interface* image; -}; - class ui_menu_software_parts : public ui_menu { public: - ui_menu_software_parts(running_machine &machine, render_container *container, ui_menu_software_entry_info *entry); + enum { T_ENTRY, T_FMGR }; + ui_menu_software_parts(running_machine &machine, render_container *container, const software_info *info, const char *interface, const software_part **part, bool opt_fmgr, int *result); virtual ~ui_menu_software_parts(); virtual void populate(); virtual void handle(); private: - struct software_part_info { - const char *part_name; - const char *interface; + struct software_part_menu_entry { + int type; + const software_part *part; }; - ui_menu_software_entry_info *entry; + const software_info *info; + const char *interface; + const software_part **selected_part; + bool opt_fmgr; + int *result; }; class ui_menu_software_list : public ui_menu { public: - ui_menu_software_list(running_machine &machine, render_container *container, software_list_config *swlist, device_image_interface *image); + ui_menu_software_list(running_machine &machine, render_container *container, const software_list_config *swlist, const char *interface, astring &result); virtual ~ui_menu_software_list(); virtual void populate(); virtual void handle(); private: - software_list_config *swlist; /* currently selected list */ - device_image_interface *image; - ui_menu_software_entry_info *entrylist; + struct entry_info { + entry_info *next; + + const char *short_name; + const char *long_name; + }; + + const software_list_config *swlist; /* currently selected list */ + const char *interface; + astring &result; + entry_info *entrylist; char filename_buffer[1024]; bool ordered_by_shortname; - int compare_entries(const ui_menu_software_entry_info *e1, const ui_menu_software_entry_info *e2, bool shortname); - ui_menu_software_entry_info *append_software_entry(software_info *swinfo, device_image_interface* image); - bool swinfo_has_multiple_parts(software_info *swinfo, const char *interface); + int compare_entries(const entry_info *e1, const entry_info *e2, bool shortname); + entry_info *append_software_entry(const software_info *swinfo); }; class ui_menu_software : public ui_menu { public: - ui_menu_software(running_machine &machine, render_container *container, device_image_interface *device); + ui_menu_software(running_machine &machine, render_container *container, const char *interface, const software_list_config **result); virtual ~ui_menu_software(); virtual void populate(); virtual void handle(); private: - device_image_interface *image; + const char *interface; + const software_list_config **result; }; #endif /* __UISWLIST_H__ */ |