diff --git a/src/emu/imagedev/floppy.c b/src/emu/imagedev/floppy.c index 19fb2704e98..a06a8d289fe 100644 --- a/src/emu/imagedev/floppy.c +++ b/src/emu/imagedev/floppy.c @@ -5,6 +5,7 @@ *********************************************************************/ #include "emu.h" +#include "emuopts.h" #include "zippath.h" #include "floppy.h" #include "formats/imageutl.h" @@ -233,16 +234,20 @@ void floppy_image_device::device_timer(emu_timer &timer, device_timer_id id, int index_resync(); } -floppy_image_format_t *floppy_image_device::identify(astring filename) const +floppy_image_format_t *floppy_image_device::identify(astring filename) { - FILE *fd; - fd = fopen(filename.cstr(), "r"); - if(!fd) + core_file *fd; + astring revised_path; + + file_error err = zippath_fopen(filename, OPEN_FLAG_READ, fd, revised_path); + if(err) { + seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to open the image file"); return 0; + } io_generic io; io.file = fd; - io.procs = &stdio_ioprocs_noclose; + io.procs = &corefile_ioprocs_noclose; io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = 0; @@ -253,7 +258,7 @@ floppy_image_format_t *floppy_image_device::identify(astring filename) const best_format = format; } } - fclose(fd); + core_fclose(fd); return best_format; } @@ -283,6 +288,9 @@ bool floppy_image_device::call_load() image = global_alloc(floppy_image(tracks, sides, form_factor)); best_format->load(&io, form_factor, image); + if(!is_readonly()) + output_format = best_format; + revolution_start_time = motor_always_on ? machine().time() : attotime::never; revolution_count = 0; @@ -725,9 +733,50 @@ void ui_menu_control_floppy_image::do_load_create() } } +astring ui_menu_control_floppy_image::try_file(astring location, astring name, bool has_crc, UINT32 crc) +{ + emu_file fd(machine().options().media_path(), OPEN_FLAG_READ); + file_error filerr; + if(has_crc) + filerr = fd.open(location.cstr(), PATH_SEPARATOR, name.cstr(), crc); + else + filerr = fd.open(location.cstr(), PATH_SEPARATOR, name.cstr()); + if(filerr != FILERR_NONE) + return ""; + return fd.fullpath(); +} + void ui_menu_control_floppy_image::hook_load(astring filename, bool softlist) { input_filename = filename; + if(softlist) { + char *swlist_name, *swname, *swpart; + software_name_split(filename.cstr(), &swlist_name, &swname, &swpart); + software_list *sw_list = software_list_open(machine().options(), swlist_name, FALSE, NULL); + software_info *sw_info = software_list_find(sw_list, swname, NULL); + software_part *sw_part = software_find_part(sw_info, swpart, NULL); + const char *parentname = software_get_clone(machine().options(), swlist_name, sw_info->shortname); + for(const rom_entry *region = sw_part->romdata; region; region = rom_next_region(region)) { + const rom_entry *romp = region + 1; + UINT32 crc = 0; + bool has_crc = hash_collection(ROM_GETHASHDATA(romp)).crc(crc); + + filename = try_file(astring(swlist_name) + PATH_SEPARATOR + astring(swname), ROM_GETNAME(romp), has_crc, crc); + if(filename == "") + filename = try_file(astring(swlist_name) + PATH_SEPARATOR + astring(parentname), ROM_GETNAME(romp), has_crc, crc); + if(filename == "") + filename = try_file(swname, ROM_GETNAME(romp), has_crc, crc); + if(filename == "") + filename = try_file(parentname, ROM_GETNAME(romp), has_crc, crc); + if(filename != "") + goto found; + } + + found: + software_list_close(sw_list); + global_free(swlist_name); + } + input_format = static_cast(image)->identify(filename); if(!input_format) { popmessage("Error: %s\n", image->error()); diff --git a/src/emu/imagedev/floppy.h b/src/emu/imagedev/floppy.h index ddb358fc932..9a7b2285d48 100644 --- a/src/emu/imagedev/floppy.h +++ b/src/emu/imagedev/floppy.h @@ -60,7 +60,7 @@ public: void set_formats(const floppy_format_type *formats); floppy_image_format_t *get_formats() const; floppy_image_format_t *get_load_format() const; - floppy_image_format_t *identify(astring filename) const; + floppy_image_format_t *identify(astring filename); void set_rpm(float rpm); // image-level overrides @@ -190,6 +190,7 @@ protected: void do_load_create(); virtual void hook_load(astring filename, bool softlist); + astring try_file(astring location, astring name, bool has_crc, UINT32 crc); }; class floppy_3_ssdd : public floppy_image_device { diff --git a/src/emu/softlist.c b/src/emu/softlist.c index 4394d2e6e1d..50a73ff726d 100644 --- a/src/emu/softlist.c +++ b/src/emu/softlist.c @@ -183,7 +183,7 @@ INLINE void unknown_attribute_value(software_list *swlist, #define global_strdup(s) strcpy(global_alloc_array(char, strlen(s) + 1), s) -static void software_name_split(const char *swlist_swname, char **swlist_name, char **swname, char **swpart ) +void software_name_split(const char *swlist_swname, char **swlist_name, char **swname, char **swpart ) { const char *split_1st_loc = strchr( swlist_swname, ':' ); const char *split_2nd_loc = ( split_1st_loc ) ? strchr( split_1st_loc + 1, ':' ) : NULL; diff --git a/src/emu/softlist.h b/src/emu/softlist.h index 74508e279f3..82192aa82c4 100644 --- a/src/emu/softlist.h +++ b/src/emu/softlist.h @@ -191,6 +191,7 @@ const software_part *software_part_next(const software_part *part); 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(const software_part *part, const char *feature_name); +void software_name_split(const char *swlist_swname, char **swlist_name, char **swname, char **swpart); 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, char**list_name); diff --git a/src/lib/formats/ioprocs.c b/src/lib/formats/ioprocs.c index 9adcf8783e7..66136f0cee1 100644 --- a/src/lib/formats/ioprocs.c +++ b/src/lib/formats/ioprocs.c @@ -2,6 +2,7 @@ #include #include "osdcore.h" #include "ioprocs.h" +#include "corefile.h" /********************************************************************* @@ -58,6 +59,60 @@ const struct io_procs stdio_ioprocs_noclose = stdio_filesizeproc }; +/********************************************************************* + ioprocs implementation on corefile +*********************************************************************/ + +static void corefile_closeproc(void *file) +{ + core_fclose((core_file*)file); +} + +static int corefile_seekproc(void *file, INT64 offset, int whence) +{ + return core_fseek((core_file*)file, (long) offset, whence); +} + +static size_t corefile_readproc(void *file, void *buffer, size_t length) +{ + return core_fread((core_file*)file, buffer, length); +} + +static size_t corefile_writeproc(void *file, const void *buffer, size_t length) +{ + return core_fwrite((core_file*)file, buffer, length); +} + +static UINT64 corefile_filesizeproc(void *file) +{ + long l, sz; + l = core_ftell((core_file*)file); + if (core_fseek((core_file*)file, 0, SEEK_END)) + return (size_t) -1; + sz = core_ftell((core_file*)file); + if (core_fseek((core_file*)file, l, SEEK_SET)) + return (size_t) -1; + return (size_t) sz; +} + +const struct io_procs corefile_ioprocs = +{ + corefile_closeproc, + corefile_seekproc, + corefile_readproc, + corefile_writeproc, + corefile_filesizeproc +}; + +const struct io_procs corefile_ioprocs_noclose = +{ + NULL, + corefile_seekproc, + corefile_readproc, + corefile_writeproc, + corefile_filesizeproc +}; + /********************************************************************* diff --git a/src/lib/formats/ioprocs.h b/src/lib/formats/ioprocs.h index f6c30866988..94239c1ba56 100644 --- a/src/lib/formats/ioprocs.h +++ b/src/lib/formats/ioprocs.h @@ -46,6 +46,8 @@ struct io_generic extern const struct io_procs stdio_ioprocs; extern const struct io_procs stdio_ioprocs_noclose; +extern const struct io_procs corefile_ioprocs; +extern const struct io_procs corefile_ioprocs_noclose;