summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/mcs51/ds5002fp.h2
-rw-r--r--src/devices/cpu/mcs51/i80c51.h2
-rw-r--r--src/devices/cpu/mcs51/i80c52.h2
-rw-r--r--src/devices/cpu/mcs51/sab80c535.h2
-rw-r--r--src/emu/ioport.cpp42
-rw-r--r--src/emu/ioport.h16
-rw-r--r--src/emu/validity.cpp33
-rw-r--r--src/emu/validity.h5
-rw-r--r--src/frontend/mame/ui/filecreate.cpp109
-rw-r--r--src/frontend/mame/ui/filecreate.h60
-rw-r--r--src/frontend/mame/ui/filemngr.cpp137
-rw-r--r--src/frontend/mame/ui/filesel.cpp48
-rw-r--r--src/frontend/mame/ui/filesel.h9
-rw-r--r--src/frontend/mame/ui/floppycntrl.cpp356
-rw-r--r--src/frontend/mame/ui/floppycntrl.h23
-rw-r--r--src/frontend/mame/ui/imgcntrl.cpp480
-rw-r--r--src/frontend/mame/ui/imgcntrl.h43
-rw-r--r--src/frontend/mame/ui/info.cpp178
-rw-r--r--src/frontend/mame/ui/info.h23
-rw-r--r--src/frontend/mame/ui/mainmenu.cpp16
-rw-r--r--src/frontend/mame/ui/menu.cpp44
-rw-r--r--src/frontend/mame/ui/midiinout.cpp81
-rw-r--r--src/frontend/mame/ui/midiinout.h24
-rw-r--r--src/frontend/mame/ui/swlist.cpp90
-rw-r--r--src/frontend/mame/ui/swlist.h58
-rw-r--r--src/lib/formats/flopimg.cpp19
-rw-r--r--src/lib/formats/flopimg.h2
-rw-r--r--src/lib/util/zippath.cpp29
-rw-r--r--src/mame/casio/pickytlk.cpp6
-rw-r--r--src/mame/sega/sega_beena.cpp4
-rw-r--r--src/mame/sega/sega_ferie.cpp6
31 files changed, 1069 insertions, 880 deletions
diff --git a/src/devices/cpu/mcs51/ds5002fp.h b/src/devices/cpu/mcs51/ds5002fp.h
index 3b7f8702799..8538c44b25d 100644
--- a/src/devices/cpu/mcs51/ds5002fp.h
+++ b/src/devices/cpu/mcs51/ds5002fp.h
@@ -6,6 +6,8 @@
#ifndef MAME_CPU_MCS51_DS5002FP_H
#define MAME_CPU_MCS51_DS5002FP_H
+#pragma once
+
#include "i8051.h"
DECLARE_DEVICE_TYPE(DS5002FP, ds5002fp_device)
diff --git a/src/devices/cpu/mcs51/i80c51.h b/src/devices/cpu/mcs51/i80c51.h
index 2d5394f763a..d2f347816da 100644
--- a/src/devices/cpu/mcs51/i80c51.h
+++ b/src/devices/cpu/mcs51/i80c51.h
@@ -4,6 +4,8 @@
#ifndef MAME_CPU_MCS51_I80C51_H
#define MAME_CPU_MCS51_I80C51_H
+#pragma once
+
#include "i8051.h"
// cmos variants
diff --git a/src/devices/cpu/mcs51/i80c52.h b/src/devices/cpu/mcs51/i80c52.h
index c472d8d4023..2b4b0f344dd 100644
--- a/src/devices/cpu/mcs51/i80c52.h
+++ b/src/devices/cpu/mcs51/i80c52.h
@@ -4,6 +4,8 @@
#ifndef MAME_CPU_MCS51_I80C52_H
#define MAME_CPU_MCS51_I80C52_H
+#pragma once
+
#include "i8052.h"
class i80c52_device : public i8052_device
diff --git a/src/devices/cpu/mcs51/sab80c535.h b/src/devices/cpu/mcs51/sab80c535.h
index 5c0b2c1cef5..bd25534f566 100644
--- a/src/devices/cpu/mcs51/sab80c535.h
+++ b/src/devices/cpu/mcs51/sab80c535.h
@@ -4,6 +4,8 @@
#ifndef MAME_CPU_MCS51_SAB80C535_H
#define MAME_CPU_MCS51_SAB80C535_H
+#pragma once
+
#include "i80c52.h"
class sab80c535_device : public i8052_device
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index fc5a0de293c..12707741cd3 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -33,6 +33,7 @@
#include <cctype>
#include <ctime>
#include <sstream>
+#include <type_traits>
namespace {
@@ -111,7 +112,7 @@ inline u8 compute_shift(ioport_value mask)
const struct
{
- u32 id;
+ input_string_index id;
const char *string;
} input_port_default_strings[] =
{
@@ -145,10 +146,10 @@ const struct
{ INPUT_STRING_3C_3C, "3 Coins/3 Credits" },
{ INPUT_STRING_2C_2C, "2 Coins/2 Credits" },
{ INPUT_STRING_1C_1C, "1 Coin/1 Credit" },
- { INPUT_STRING_3C_5C, "3 Coins/5 Credits" },
{ INPUT_STRING_4C_5C, "4 Coins/5 Credits" },
{ INPUT_STRING_3C_4C, "3 Coins/4 Credits" },
{ INPUT_STRING_2C_3C, "2 Coins/3 Credits" },
+ { INPUT_STRING_3C_5C, "3 Coins/5 Credits" },
{ INPUT_STRING_4C_7C, "4 Coins/7 Credits" },
{ INPUT_STRING_2C_4C, "2 Coins/4 Credits" },
{ INPUT_STRING_1C_2C, "1 Coin/2 Credits" },
@@ -3304,27 +3305,21 @@ ioport_configurer& ioport_configurer::field_set_gm_note(u8 note)
// ioport_token to a default string
//-------------------------------------------------
-const char *ioport_configurer::string_from_token(const char *string)
+const char *ioport_configurer::string_from_token(input_string_index string)
{
- // 0 is an invalid index
- if (string == nullptr)
- return nullptr;
-
- // if the index is greater than the count, assume it to be a pointer
- if (uintptr_t(string) >= INPUT_STRING_COUNT)
- return string;
-
-#if false // Set true, If you want to take care missing-token or wrong-sorting
+#if 0 // Set true, If you want to take care missing-token or wrong-sorting
// otherwise, scan the list for a matching string and return it
for (int index = 0; index < std::size(input_port_default_strings); index++)
- if (input_port_default_strings[index].id == uintptr_t(string))
+ if (input_port_default_strings[index].id == string)
return input_port_default_strings[index].string;
return "(Unknown Default)";
#else
- return input_port_default_strings[uintptr_t(string)-1].string;
+ auto const index = std::underlying_type_t<input_string_index>(string) - 1;
+ assert(input_port_default_strings[index].id == string);
+ return input_port_default_strings[index].string;
#endif
}
@@ -3384,7 +3379,7 @@ ioport_configurer& ioport_configurer::field_alloc(ioport_type type, ioport_value
// append the field
if (type != IPT_UNKNOWN && type != IPT_UNUSED)
m_curport->m_active |= mask;
- m_curfield = &m_curport->m_fieldlist.append(*new ioport_field(*m_curport, type, defval, mask, string_from_token(name)));
+ m_curfield = &m_curport->m_fieldlist.append(*new ioport_field(*m_curport, type, defval, mask, name));
// reset the current setting
m_cursetting = nullptr;
@@ -3392,6 +3387,11 @@ ioport_configurer& ioport_configurer::field_alloc(ioport_type type, ioport_value
return *this;
}
+ioport_configurer& ioport_configurer::field_alloc(ioport_type type, ioport_value defval, ioport_value mask, input_string_index name)
+{
+ return field_alloc(type, defval, mask, string_from_token(name));
+}
+
//-------------------------------------------------
// field_add_char - add a character to a field
@@ -3444,10 +3444,15 @@ ioport_configurer& ioport_configurer::setting_alloc(ioport_value value, const ch
throw emu_fatalerror("setting_alloc called with no active field (value=%X name=%s)\n", value, name);
// append a new setting
- m_cursetting = &m_curfield->m_settinglist.emplace_back(*m_curfield, value & m_curfield->mask(), string_from_token(name));
+ m_cursetting = &m_curfield->m_settinglist.emplace_back(*m_curfield, value & m_curfield->mask(), name);
return *this;
}
+ioport_configurer& ioport_configurer::setting_alloc(ioport_value value, input_string_index name)
+{
+ return setting_alloc(value, string_from_token(name));
+}
+
//-------------------------------------------------
// set_condition - set the condition for either
@@ -3483,6 +3488,11 @@ ioport_configurer& ioport_configurer::onoff_alloc(const char *name, ioport_value
return *this;
}
+ioport_configurer& ioport_configurer::onoff_alloc(input_string_index name, ioport_value defval, ioport_value mask, const char *diplocation)
+{
+ return onoff_alloc(string_from_token(name), defval, mask, diplocation);
+}
+
/***************************************************************************
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index d018cdf1ffa..b40b0272086 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -97,7 +97,7 @@ enum ioport_type_class
// default strings used in port definitions
-enum
+enum input_string_index
{
INPUT_STRING_Off = 1,
INPUT_STRING_On,
@@ -1035,7 +1035,7 @@ public:
ioport_configurer(device_t &owner, ioport_list &portlist, std::ostream &errorbuf);
// static helpers
- static const char *string_from_token(const char *string);
+ static const char *string_from_token(input_string_index string);
// port helpers
ioport_configurer& port_alloc(const char *tag);
@@ -1043,10 +1043,12 @@ public:
// field helpers
ioport_configurer& field_alloc(ioport_type type, ioport_value defval, ioport_value mask, const char *name = nullptr);
+ ioport_configurer& field_alloc(ioport_type type, ioport_value defval, ioport_value mask, input_string_index name);
ioport_configurer& field_add_char(std::initializer_list<char32_t> charlist);
ioport_configurer& field_add_code(input_seq_type which, input_code code);
ioport_configurer& field_set_way(int way) { m_curfield->m_way = way; return *this; }
- ioport_configurer& field_set_name(const char *name) { assert(m_curfield != nullptr); m_curfield->m_name = string_from_token(name); return *this; }
+ ioport_configurer& field_set_name(const char *name) { assert(m_curfield != nullptr); m_curfield->m_name = name; return *this; }
+ ioport_configurer& field_set_name(input_string_index name) { assert(m_curfield != nullptr); m_curfield->m_name = string_from_token(name); return *this; }
ioport_configurer& field_set_player(int player) { m_curfield->m_player = player - 1; return *this; }
ioport_configurer& field_set_cocktail() { m_curfield->m_flags |= ioport_field::FIELD_FLAG_COCKTAIL; field_set_player(2); return *this; }
ioport_configurer& field_set_toggle() { m_curfield->m_flags |= ioport_field::FIELD_FLAG_TOGGLE; return *this; }
@@ -1071,10 +1073,12 @@ public:
// setting helpers
ioport_configurer& setting_alloc(ioport_value value, const char *name);
+ ioport_configurer& setting_alloc(ioport_value value, input_string_index name);
// misc helpers
ioport_configurer& set_condition(ioport_condition::condition_t condition, const char *tag, ioport_value mask, ioport_value value);
ioport_configurer& onoff_alloc(const char *name, ioport_value defval, ioport_value mask, const char *diplocation);
+ ioport_configurer& onoff_alloc(input_string_index name, ioport_value defval, ioport_value mask, const char *diplocation);
// allow UTF-8 strings to be used for names transparently
ioport_configurer& field_alloc(ioport_type type, ioport_value defval, ioport_value mask, const char8_t *name) { return field_alloc(type, defval, mask, reinterpret_cast<const char *>(name)); }
@@ -1106,12 +1110,8 @@ private:
#define INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, u32 param, ioport_value oldval, ioport_value newval)
#define DECLARE_INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, u32 param, ioport_value oldval, ioport_value newval)
-// macro for port changed callback functions (PORT_CROSSHAIR_MAPPER)
-#define CROSSHAIR_MAPPER_MEMBER(name) float name(float linear_value)
-#define DECLARE_CROSSHAIR_MAPPER_MEMBER(name) float name(float linear_value)
-
// macro for wrapping a default string
-#define DEF_STR(str_num) ((const char *)INPUT_STRING_##str_num)
+#define DEF_STR(str_num) (INPUT_STRING_##str_num)
diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp
index b65e1faf3c9..e93ee223be4 100644
--- a/src/emu/validity.cpp
+++ b/src/emu/validity.cpp
@@ -117,17 +117,6 @@ struct pure_virtual_base
//-------------------------------------------------
-// ioport_string_from_index - return an indexed
-// string from the I/O port system
-//-------------------------------------------------
-
-inline char const *ioport_string_from_index(u32 index)
-{
- return ioport_configurer::string_from_token(reinterpret_cast<char const *>(uintptr_t(index)));
-}
-
-
-//-------------------------------------------------
// random_u64
// random_s64
// random_u32
@@ -1894,13 +1883,13 @@ void validate_delegates_functoid()
// strings
//-------------------------------------------------
-inline int validity_checker::get_defstr_index(const char *string, bool suppress_error)
+inline input_string_index validity_checker::get_defstr_index(const char *string, bool suppress_error)
{
// check for strings that should be DEF_STR
- auto strindex = m_defstr_map.find(string);
- if (!suppress_error && strindex != m_defstr_map.end() && string != ioport_string_from_index(strindex->second))
+ auto const strindex = m_defstr_map.find(string);
+ if (!suppress_error && (strindex != m_defstr_map.end()) && (string != ioport_configurer::string_from_token(strindex->second)))
osd_printf_error("Must use DEF_STR( %s )\n", string);
- return (strindex != m_defstr_map.end()) ? strindex->second : 0;
+ return (strindex != m_defstr_map.end()) ? strindex->second : input_string_index(0);
}
@@ -1978,9 +1967,9 @@ validity_checker::validity_checker(emu_options &options, bool quick)
// pre-populate the defstr map with all the default strings
for (int strnum = 1; strnum < INPUT_STRING_COUNT; strnum++)
{
- const char *string = ioport_string_from_index(strnum);
+ const char *string = ioport_configurer::string_from_token(input_string_index(strnum));
if (string != nullptr)
- m_defstr_map.insert(std::make_pair(string, strnum));
+ m_defstr_map.emplace(string, input_string_index(strnum));
}
}
@@ -2579,8 +2568,8 @@ void validity_checker::validate_analog_input_field(const ioport_field &field)
void validity_checker::validate_dip_settings(const ioport_field &field)
{
- char const *const demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds);
- char const *const flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen);
+ char const *const demo_sounds = ioport_configurer::string_from_token(INPUT_STRING_Demo_Sounds);
+ char const *const flipscreen = ioport_configurer::string_from_token(INPUT_STRING_Flip_Screen);
char const *const name = field.specific_name() ? field.specific_name() : "UNNAMED";
u8 coin_list[__input_string_coinage_end + 1 - __input_string_coinage_start] = { 0 };
bool coin_error = false;
@@ -2589,7 +2578,7 @@ void validity_checker::validate_dip_settings(const ioport_field &field)
for (auto setting = field.settings().begin(); field.settings().end() != setting; ++setting)
{
// note any coinage strings
- int strindex = get_defstr_index(setting->name());
+ input_string_index const strindex = get_defstr_index(setting->name());
if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end)
coin_list[strindex - __input_string_coinage_start] = 1;
@@ -2610,7 +2599,7 @@ void validity_checker::validate_dip_settings(const ioport_field &field)
if (field.settings().end() != nextsetting)
{
// check for inverted off/on DIP switch order
- int next_strindex = get_defstr_index(nextsetting->name(), true);
+ input_string_index next_strindex = get_defstr_index(nextsetting->name(), true);
if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off)
osd_printf_error("%s option must have Off/On options in the order: Off, On\n", name);
@@ -2638,7 +2627,7 @@ void validity_checker::validate_dip_settings(const ioport_field &field)
output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, " Note proper coin sort order should be:\n");
for (int entry = 0; entry < std::size(coin_list); entry++)
if (coin_list[entry])
- output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, " %s\n", ioport_string_from_index(__input_string_coinage_start + entry));
+ output_via_delegate(OSD_OUTPUT_CHANNEL_ERROR, " %s\n", ioport_configurer::string_from_token(input_string_index(__input_string_coinage_start + entry)));
}
}
diff --git a/src/emu/validity.h b/src/emu/validity.h
index fbf5f239323..6b15164454e 100644
--- a/src/emu/validity.h
+++ b/src/emu/validity.h
@@ -56,11 +56,12 @@ protected:
private:
// internal map types
using game_driver_map = std::unordered_map<std::string, game_driver const *>;
+ using input_string_map = std::unordered_map<std::string, input_string_index>;
using int_map = std::unordered_map<std::string, uintptr_t>;
using string_set = std::unordered_set<std::string>;
// internal helpers
- int get_defstr_index(const char *string, bool suppress_error = false);
+ input_string_index get_defstr_index(const char *string, bool suppress_error = false);
// core helpers
void validate_begin();
@@ -100,7 +101,7 @@ private:
game_driver_map m_names_map;
game_driver_map m_descriptions_map;
game_driver_map m_roms_map;
- int_map m_defstr_map;
+ input_string_map m_defstr_map;
// current state
game_driver const * m_current_driver;
diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp
index 8dd564aa03b..1d01f5d856e 100644
--- a/src/frontend/mame/ui/filecreate.cpp
+++ b/src/frontend/mame/ui/filecreate.cpp
@@ -19,7 +19,6 @@
#include "formats/flopimg.h"
-#include "path.h"
#include "zippath.h"
#include <cstring>
@@ -31,7 +30,7 @@ namespace ui {
CONSTANTS
***************************************************************************/
-// conditional compilation to enable chosing of image formats - this is not
+// conditional compilation to enable choosing of image formats - this is not
// yet fully implemented
#define ENABLE_FORMATS 0
@@ -55,11 +54,14 @@ CONFIRM SAVE AS MENU
// ctor
//-------------------------------------------------
-menu_confirm_save_as::menu_confirm_save_as(mame_ui_manager &mui, render_target &target, bool &yes)
+menu_confirm_save_as::menu_confirm_save_as(
+ mame_ui_manager &mui,
+ render_target &target,
+ handler_function &&handler)
: menu(mui, target)
- , m_yes(yes)
+ , m_handler(std::move(handler))
{
- m_yes = false;
+ set_needs_prev_menu_item(false);
}
@@ -78,7 +80,7 @@ menu_confirm_save_as::~menu_confirm_save_as()
void menu_confirm_save_as::populate()
{
- item_append(_("File Already Exists - Override?"), FLAG_DISABLE, nullptr);
+ item_append(_("File Already Exists - Overwrite?"), FLAG_DISABLE, nullptr);
item_append(menu_item_type::SEPARATOR);
item_append(_("No"), 0, ITEMREF_NO);
item_append(_("Yes"), 0, ITEMREF_YES);
@@ -94,10 +96,9 @@ bool menu_confirm_save_as::handle(event const *ev)
if (ev && (ev->iptkey == IPT_UI_SELECT))
{
if (ev->itemref == ITEMREF_YES)
- m_yes = true;
-
- // no matter what, pop out
- stack_pop();
+ m_handler();
+ else
+ stack_pop();
}
return false;
@@ -113,18 +114,21 @@ FILE CREATE MENU
// ctor
//-------------------------------------------------
-menu_file_create::menu_file_create(mame_ui_manager &mui, render_target &target, device_image_interface *image, std::string &current_directory, std::string &current_file, bool &ok)
+menu_file_create::menu_file_create(
+ mame_ui_manager &mui,
+ render_target &target,
+ device_image_interface &image,
+ std::string_view current_directory,
+ std::string &&starting_name,
+ handler_function &&handler)
: menu(mui, target)
- , m_ok(ok)
+ , m_handler(std::move(handler))
+ , m_image(image)
, m_current_directory(current_directory)
- , m_current_file(current_file)
, m_current_format(nullptr)
+ , m_filename(std::move(starting_name))
{
- m_image = image;
- m_ok = false;
-
m_filename.reserve(1024);
- m_filename = core_filename_extract_base(current_file);
}
@@ -193,7 +197,7 @@ void menu_file_create::populate()
item_append(_("New Image Name:"), *new_image_name, 0, ITEMREF_NEW_IMAGE_NAME);
// do we support multiple formats?
- image_device_format const *const format = ENABLE_FORMATS ? m_image->formatlist().front().get() : nullptr;
+ image_device_format const *const format = ENABLE_FORMATS ? m_image.formatlist().front().get() : nullptr;
if (format)
{
// FIXME: is this in the right order? It reassigns m_current_format after reading it.
@@ -224,15 +228,9 @@ bool menu_file_create::handle(event const *ev)
{
std::string tmp_file(m_filename);
if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1)
- {
- m_current_file = m_filename;
- m_ok = true;
- stack_pop();
- }
+ m_handler(m_filename);
else
- {
- ui().popup_time(1, "%s", _("Please enter a file extension too"));
- }
+ ui().popup_time(1, "%s", _("Please enter a file name extension, too"));
}
break;
@@ -280,12 +278,29 @@ SELECT FORMAT MENU
// ctor
//-------------------------------------------------
-menu_select_format::menu_select_format(mame_ui_manager &mui, render_target &target, const std::vector<const floppy_image_format_t *> &formats, int ext_match, const floppy_image_format_t **result)
+menu_select_format::menu_select_format(
+ mame_ui_manager &mui,
+ render_target &target,
+ floppy_image_device &fd,
+ std::string_view name,
+ handler_function &&handler)
: menu(mui, target)
+ , m_handler(std::move(handler))
{
- m_formats = formats;
- m_ext_match = ext_match;
- m_result = result;
+ m_formats.reserve(fd.get_formats().size());
+ for (floppy_image_format_t const *i : fd.get_formats())
+ {
+ if (i->supports_save() && i->extension_matches(name))
+ m_formats.emplace_back(i);
+ }
+ m_ext_match = m_formats.size();
+ for (floppy_image_format_t const *i : fd.get_formats())
+ {
+ if (i->supports_save() && !i->extension_matches(name))
+ m_formats.emplace_back(i);
+ }
+
+ set_heading(_("Select image format"));
}
@@ -304,15 +319,16 @@ menu_select_format::~menu_select_format()
void menu_select_format::populate()
{
- item_append(_("Select image format"), FLAG_DISABLE, nullptr);
for (unsigned int i = 0; i != m_formats.size(); i++)
{
const floppy_image_format_t *fmt = m_formats[i];
- if (i && i == m_ext_match)
+ if (i && (i == m_ext_match))
item_append(menu_item_type::SEPARATOR);
item_append(fmt->description(), fmt->name(), 0, const_cast<floppy_image_format_t *>(fmt));
}
+
+ item_append(menu_item_type::SEPARATOR);
}
@@ -323,11 +339,8 @@ void menu_select_format::populate()
bool menu_select_format::handle(event const *ev)
{
// process the menu
- if (ev && ev->iptkey == IPT_UI_SELECT)
- {
- *m_result = (floppy_image_format_t *)ev->itemref;
- stack_pop();
- }
+ if (ev && (ev->iptkey == IPT_UI_SELECT))
+ m_handler(*reinterpret_cast<floppy_image_format_t const *>(ev->itemref));
return false;
}
@@ -341,12 +354,16 @@ SELECT FORMAT MENU
// ctor
//-------------------------------------------------
-menu_select_floppy_init::menu_select_floppy_init(mame_ui_manager &mui, render_target &target, std::vector<std::reference_wrapper<const floppy_image_device::fs_info>> &&fs, int *result)
+menu_select_floppy_init::menu_select_floppy_init(
+ mame_ui_manager &mui,
+ render_target &target,
+ std::vector<std::reference_wrapper<floppy_image_device::fs_info const> > &&fs,
+ handler_function &&handler)
: menu(mui, target)
+ , m_handler(std::move(handler))
, m_fs(std::move(fs))
- , m_result(result)
-
{
+ set_heading(_("Select initial contents"));
}
@@ -365,10 +382,9 @@ menu_select_floppy_init::~menu_select_floppy_init()
void menu_select_floppy_init::populate()
{
- item_append(_("Select initial contents"), FLAG_DISABLE, nullptr);
- int id = 0;
- for (const floppy_image_device::fs_info &fmt : m_fs)
- item_append(fmt.m_description, fmt.m_name, 0, (void *)(uintptr_t)(id++));
+ for (floppy_image_device::fs_info const &fs : m_fs)
+ item_append(fs.m_description, fs.m_name, 0, &const_cast<floppy_image_device::fs_info &>(fs));
+ item_append(menu_item_type::SEPARATOR);
}
@@ -380,10 +396,7 @@ bool menu_select_floppy_init::handle(event const *ev)
{
// process the menu
if (ev && ev->iptkey == IPT_UI_SELECT)
- {
- *m_result = int(uintptr_t(ev->itemref));
- stack_pop();
- }
+ m_handler(*reinterpret_cast<floppy_image_device::fs_info const *>(ev->itemref));
return false;
}
diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h
index 91bdac0ce47..6ecfb354460 100644
--- a/src/frontend/mame/ui/filecreate.h
+++ b/src/frontend/mame/ui/filecreate.h
@@ -17,6 +17,11 @@
#include "imagedev/floppy.h"
+#include <functional>
+#include <string>
+#include <string_view>
+#include <vector>
+
class floppy_image_format_t;
@@ -27,14 +32,16 @@ namespace ui {
class menu_confirm_save_as : public menu
{
public:
- menu_confirm_save_as(mame_ui_manager &mui, render_target &target, bool &yes);
+ using handler_function = std::function<void ()>;
+
+ menu_confirm_save_as(mame_ui_manager &mui, render_target &target, handler_function &&handler);
virtual ~menu_confirm_save_as() override;
private:
virtual void populate() override;
virtual bool handle(event const *ev) override;
- bool &m_yes;
+ handler_function m_handler;
};
@@ -43,7 +50,15 @@ private:
class menu_file_create : public menu
{
public:
- menu_file_create(mame_ui_manager &mui, render_target &target, device_image_interface *image, std::string &current_directory, std::string &current_file, bool &ok);
+ using handler_function = std::function<void (std::string const &)>;
+
+ menu_file_create(
+ mame_ui_manager &mui,
+ render_target &target,
+ device_image_interface &image,
+ std::string_view current_directory,
+ std::string &&starting_name,
+ handler_function &&handler);
virtual ~menu_file_create() override;
protected:
@@ -55,11 +70,10 @@ private:
virtual void populate() override;
virtual bool handle(event const *ev) override;
- bool & m_ok;
- device_image_interface * m_image;
- std::string & m_current_directory;
- std::string & m_current_file;
- const image_device_format * m_current_format;
+ handler_function m_handler;
+ device_image_interface & m_image;
+ std::string_view const m_current_directory;
+ image_device_format const * m_current_format;
std::string m_filename;
};
@@ -68,8 +82,15 @@ private:
class menu_select_format : public menu
{
public:
- menu_select_format(mame_ui_manager &mui, render_target &target,
- const std::vector<const floppy_image_format_t *> &formats, int ext_match, const floppy_image_format_t **result);
+ using handler_function = std::function<void (floppy_image_format_t const &)>;
+
+ menu_select_format(
+ mame_ui_manager &mui,
+ render_target &target,
+ floppy_image_device &fd,
+ std::string_view name,
+ handler_function &&handler);
+
virtual ~menu_select_format() override;
private:
@@ -77,9 +98,9 @@ private:
virtual bool handle(event const *ev) override;
// internal state
- std::vector<const floppy_image_format_t *> m_formats;
- int m_ext_match;
- const floppy_image_format_t * *m_result;
+ handler_function const m_handler;
+ std::vector<floppy_image_format_t const *> m_formats;
+ size_t m_ext_match;
};
// ======================> menu_select_floppy_init
@@ -87,8 +108,13 @@ private:
class menu_select_floppy_init : public menu
{
public:
- menu_select_floppy_init(mame_ui_manager &mui, render_target &target,
- std::vector<std::reference_wrapper<const floppy_image_device::fs_info>> &&fs, int *result);
+ using handler_function = std::function<void (floppy_image_device::fs_info const &)>;
+
+ menu_select_floppy_init(
+ mame_ui_manager &mui,
+ render_target &target,
+ std::vector<std::reference_wrapper<floppy_image_device::fs_info const> > &&fs,
+ handler_function &&handler);
virtual ~menu_select_floppy_init() override;
private:
@@ -96,8 +122,8 @@ private:
virtual bool handle(event const *ev) override;
// internal state
- std::vector<std::reference_wrapper<const floppy_image_device::fs_info>> m_fs;
- int * m_result;
+ handler_function const m_handler;
+ std::vector<std::reference_wrapper<floppy_image_device::fs_info const > > m_fs;
};
diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp
index 80f6eb067b7..85dd66c6ae3 100644
--- a/src/frontend/mame/ui/filemngr.cpp
+++ b/src/frontend/mame/ui/filemngr.cpp
@@ -45,7 +45,7 @@ menu_file_manager::menu_file_manager(mame_ui_manager &mui, render_target &target
{
// The 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
- set_heading(_("File Manager"));
+ set_heading(_("Media Control"));
}
@@ -74,11 +74,11 @@ void menu_file_manager::recompute_metrics(uint32_t width, uint32_t height, float
m_warnings_layout.emplace(create_layout(max_width, text_layout::text_justify::LEFT));
m_warnings_layout->add_text(m_warnings, ui().colors().text_color());
- set_custom_space(0.0F, (float(m_warnings_layout->lines() + 1) * line_height()) + (6.0F * tb_border()));
+ set_custom_space(0.0F, (float(m_warnings_layout->lines() + 3) * line_height()) + (6.0F * tb_border()));
}
else
{
- set_custom_space(0.0F, line_height() + (3.0F * tb_border()));
+ set_custom_space(0.0F, (3.0F * line_height()) + (3.0F * tb_border()));
}
}
@@ -91,7 +91,47 @@ void menu_file_manager::custom_render(uint32_t flags, void *selectedref, float t
{
// access the path
if (m_selected_device && m_selected_device->exists())
- extra_text_render(top, (3.0F * tb_border()) + line_height(), origx1, origy1, origx2, origy2, std::string_view(), m_selected_device->filename());
+ {
+ if (m_selected_device->has_preset_images_selection())
+ {
+ extra_text_render(
+ top, (3.0F * tb_border()) + line_height(), origx1, origy1, origx2, origy2,
+ std::string_view(),
+ util::string_format(_("%1$s preset %2$u"), m_selected_device->filename(), m_selected_device->current_preset_image_id() + 1));
+ }
+ else if (!m_selected_device->loaded_through_softlist())
+ {
+ extra_text_render(
+ top, (3.0F * tb_border()) + line_height(), origx1, origy1, origx2, origy2,
+ std::string_view(),
+ m_selected_device->filename());
+ }
+ else
+ {
+ software_info const &swinfo(*m_selected_device->software_entry());
+ unsigned const lines((swinfo.supported() == software_support::SUPPORTED) ? 2 : 3);
+ std::string const line2(util::string_format(_("%1$s, %2$s"), swinfo.publisher(), swinfo.year()));
+ std::string_view text[3];
+ text[0] = swinfo.longname();
+ text[1] = line2;
+ switch (swinfo.supported())
+ {
+ case software_support::UNSUPPORTED:
+ text[2] = _("Not supported");
+ break;
+ case software_support::PARTIALLY_SUPPORTED:
+ text[2] = _("Partially supported");
+ break;
+ case software_support::SUPPORTED:
+ break;
+ }
+ draw_text_box(
+ std::begin(text), std::next(std::begin(text), lines),
+ origx1, origx2, origy2 + tb_border(), origy2 + (lines * line_height()) + (3.0F * tb_border()),
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
+ ui().colors().text_color(), ui().colors().background_color());
+ }
+ }
// show the warnings if any
if (m_warnings_layout)
@@ -130,9 +170,9 @@ void menu_file_manager::fill_image_line(device_image_interface &img, std::string
software_part const *const part = img.part_entry();
auto const partid = img.get_feature("part_id");
if (partid)
- filename = string_format(_("%1$s (%2$s: %3$s)"), img.basename(), part->name(), partid);
+ filename = string_format(_("%1$s:%2$s (%3$s)"), img.basename(), part->name(), partid);
else
- filename = string_format(_("%1$s (%2$s)"), img.basename(), part->name());
+ filename = string_format(_("%1$s:%2$s"), img.basename(), part->name());
}
}
@@ -146,64 +186,47 @@ void menu_file_manager::populate()
// cycle through all devices for this system
bool missing_mandatory = false;
- std::unordered_set<std::string> devtags;
std::string tmp_inst, tmp_name;
+ device_t *prev_parent = nullptr;
for (device_t &dev : device_enumerator(machine().root_device()))
{
- bool tag_appended = false;
- if (!devtags.insert(dev.tag()).second)
- continue;
-
// check whether it owns an image interface
- image_interface_enumerator subiter(dev);
- if (subiter.first() != nullptr)
+ for (device_image_interface &scan : image_interface_enumerator(dev, 1))
{
- // if so, cycle through all its image interfaces
- for (device_image_interface &scan : subiter)
+ if ((&scan.device() == &dev) || (!scan.has_preset_images_selection() && !scan.user_loadable()))
+ continue;
+
+ // check whether we already had some devices with the same owner: if not, output the owner tag!
+ if (&dev != prev_parent)
{
- if (scan.has_preset_images_selection())
- {
- if (devtags.insert(scan.device().tag()).second)
- {
- item_append(string_format(_("[root%1$s]"), scan.device().owner()->tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr);
- int const index = item_append(scan.image_type_name(), scan.preset_images_list()[scan.current_preset_image_id()], 0, (void *)&scan);
- m_notifiers.emplace_back(scan.add_media_change_notifier(
- [this, index, &scan] (device_image_interface::media_change_event ev)
- {
- item(index).set_subtext(scan.preset_images_list()[scan.current_preset_image_id()]);
- }));
- }
- }
- else if (scan.user_loadable())
- {
- // if it is a child device, and not something further down the device tree, we want it in the menu!
- if (!strcmp(scan.device().owner()->tag(), dev.tag()))
- {
- if (devtags.insert(scan.device().tag()).second)
+ item_append(string_format(_("[root%1$s]"), dev.tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr);
+ prev_parent = &dev;
+ }
+
+ if (scan.has_preset_images_selection())
+ {
+ int const index = item_append(scan.image_type_name(), scan.preset_images_list()[scan.current_preset_image_id()], 0, (void *)&scan);
+ m_notifiers.emplace_back(scan.add_media_change_notifier(
+ [this, index, &scan] (device_image_interface::media_change_event ev)
{
- if (!scan.basename() && scan.must_be_loaded())
- missing_mandatory = true;
-
- // check whether we already had some devices with the same owner: if not, output the owner tag!
- if (!tag_appended)
- {
- item_append(string_format(_("[root%1$s]"), dev.tag()), FLAG_UI_HEADING | FLAG_DISABLE, nullptr);
- tag_appended = true;
- }
-
- // finally, append the image interface to the menu
- fill_image_line(scan, tmp_inst, tmp_name);
- int const index = item_append(std::move(tmp_inst), std::move(tmp_name), 0, (void *)&scan);
- m_notifiers.emplace_back(scan.add_media_change_notifier(
- [this, index, &scan] (device_image_interface::media_change_event ev)
- {
- std::string text, subtext;
- fill_image_line(scan, text, subtext);
- item(index).set_subtext(std::move(subtext));
- }));
- }
- }
- }
+ item(index).set_subtext(scan.preset_images_list()[scan.current_preset_image_id()]);
+ }));
+ }
+ else if (scan.user_loadable())
+ {
+ if (!scan.basename() && scan.must_be_loaded())
+ missing_mandatory = true;
+
+ // finally, append the image interface to the menu
+ fill_image_line(scan, tmp_inst, tmp_name);
+ int const index = item_append(std::move(tmp_inst), std::move(tmp_name), 0, (void *)&scan);
+ m_notifiers.emplace_back(scan.add_media_change_notifier(
+ [this, index, &scan] (device_image_interface::media_change_event ev)
+ {
+ std::string text, subtext;
+ fill_image_line(scan, text, subtext);
+ item(index).set_subtext(std::move(subtext));
+ }));
}
}
}
diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp
index a70eb4f6094..cb7fc6f3451 100644
--- a/src/frontend/mame/ui/filesel.cpp
+++ b/src/frontend/mame/ui/filesel.cpp
@@ -56,7 +56,7 @@ namespace ui {
menu_file_selector::menu_file_selector(
mame_ui_manager &mui,
render_target &target,
- device_image_interface *image,
+ device_image_interface &image,
std::string_view directory,
std::string_view file,
bool has_empty,
@@ -65,17 +65,14 @@ menu_file_selector::menu_file_selector(
handler_function &&handler)
: menu(mui, target)
, m_handler(std::move(handler))
- , m_image(image)
, m_current_directory(directory)
, m_current_file(file)
- , m_result(result::INVALID)
, m_has_empty(has_empty)
, m_has_softlist(has_softlist)
, m_has_create(has_create)
- , m_is_midi(image->device().type() == MIDIIN || image->device().type() == MIDIOUT)
+ , m_is_midi((image.device().type() == MIDIIN) || (image.device().type() == MIDIOUT))
, m_clicked_directory(std::string::npos, std::string::npos)
{
- (void)m_image;
set_process_flags(PROCESS_IGNOREPAUSE);
}
@@ -86,8 +83,6 @@ menu_file_selector::menu_file_selector(
menu_file_selector::~menu_file_selector()
{
- if (m_handler)
- m_handler(m_result, std::move(m_current_directory), std::move(m_current_file));
}
@@ -324,7 +319,7 @@ void menu_file_selector::append_entry_menu_item(const file_selector_entry *entry
break;
case SELECTOR_ENTRY_TYPE_MIDI:
- text = _("[midi port]");
+ text = _("[MIDI port]");
break;
case SELECTOR_ENTRY_TYPE_CREATE:
@@ -363,26 +358,19 @@ void menu_file_selector::select_item(const file_selector_entry &entry)
switch (entry.type)
{
case SELECTOR_ENTRY_TYPE_EMPTY:
- // empty slot - unload
- m_result = result::EMPTY;
- stack_pop();
+ m_handler(result::EMPTY, m_current_directory, m_current_file);
break;
case SELECTOR_ENTRY_TYPE_MIDI:
- // create
- m_result = result::MIDI;
- stack_pop();
+ m_handler(result::MIDI, m_current_directory, m_current_file);
break;
case SELECTOR_ENTRY_TYPE_CREATE:
- // create
- m_result = result::CREATE;
- stack_pop();
+ m_handler(result::CREATE, m_current_directory, m_current_file);
break;
case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST:
- m_result = result::SOFTLIST;
- stack_pop();
+ m_handler(result::SOFTLIST, m_current_directory, m_current_file);
break;
case SELECTOR_ENTRY_TYPE_DRIVE:
@@ -407,8 +395,7 @@ void menu_file_selector::select_item(const file_selector_entry &entry)
case SELECTOR_ENTRY_TYPE_FILE:
// file
m_current_file.assign(entry.fullpath);
- m_result = result::FILE;
- stack_pop();
+ m_handler(result::FILE, m_current_directory, m_current_file);
break;
}
}
@@ -570,6 +557,7 @@ void menu_file_selector::populate()
// append all of the menu entries
for (file_selector_entry const &entry : m_entrylist)
append_entry_menu_item(&entry);
+ item_append(menu_item_type::SEPARATOR);
// set the selection (if we have one)
if (selected_entry)
@@ -627,11 +615,10 @@ bool menu_file_selector::handle(event const *ev)
}
else if (ev->itemref && (ev->iptkey == IPT_UI_SELECT))
{
- // handle selections
- select_item(*reinterpret_cast<file_selector_entry const *>(ev->itemref));
-
- // reset the char buffer when pressing IPT_UI_SELECT
+ // reset search when selecting an item
m_filename.clear();
+
+ select_item(*reinterpret_cast<file_selector_entry const *>(ev->itemref));
return true;
}
@@ -656,7 +643,6 @@ menu_select_rw::menu_select_rw(
: menu(mui, target)
, m_handler(std::move(handler))
, m_can_in_place(can_in_place)
- , m_result(result::INVALID)
{
}
@@ -667,8 +653,6 @@ menu_select_rw::menu_select_rw(
menu_select_rw::~menu_select_rw()
{
- if (m_handler)
- m_handler(m_result);
}
@@ -684,7 +668,8 @@ void menu_select_rw::populate()
if (m_can_in_place)
item_append(_("Read-write"), 0, itemref_from_result(result::READWRITE));
item_append(_("Read this image, write to another image"), 0, itemref_from_result(result::WRITE_OTHER));
- item_append(_("Read this image, write to diff"), 0, itemref_from_result(result::WRITE_DIFF));
+ //item_append(_("Read this image, write to diff"), 0, itemref_from_result(result::WRITE_DIFF));
+ item_append(menu_item_type::SEPARATOR);
}
@@ -695,10 +680,7 @@ void menu_select_rw::populate()
bool menu_select_rw::handle(event const *ev)
{
if (ev && ev->iptkey == IPT_UI_SELECT)
- {
- m_result = result_from_itemref(ev->itemref);
- stack_pop();
- }
+ m_handler(result_from_itemref(ev->itemref));
return false;
}
diff --git a/src/frontend/mame/ui/filesel.h b/src/frontend/mame/ui/filesel.h
index 37bc69ff4ce..351a8b954bf 100644
--- a/src/frontend/mame/ui/filesel.h
+++ b/src/frontend/mame/ui/filesel.h
@@ -33,7 +33,6 @@ class menu_file_selector : public menu
public:
enum class result
{
- INVALID = -1,
EMPTY = 0x1000,
SOFTLIST,
CREATE,
@@ -41,12 +40,12 @@ public:
MIDI
};
- using handler_function = std::function<void (result result, std::string &&directory, std::string &&file)>;
+ using handler_function = std::function<void (result result, std::string const &directory, std::string const &file)>;
menu_file_selector(
mame_ui_manager &mui,
render_target &target,
- device_image_interface *image,
+ device_image_interface &image,
std::string_view directory,
std::string_view file,
bool has_empty,
@@ -87,12 +86,10 @@ private:
// internal state
handler_function const m_handler;
- device_image_interface *const m_image;
std::string m_current_directory;
std::string m_current_file;
std::optional<text_layout> m_path_layout;
std::pair<float, float> m_path_position;
- result m_result;
bool const m_has_empty;
bool const m_has_softlist;
bool const m_has_create;
@@ -122,7 +119,6 @@ class menu_select_rw : public menu
public:
enum class result
{
- INVALID = -1,
READONLY = 0x3000,
READWRITE,
WRITE_OTHER,
@@ -148,7 +144,6 @@ private:
// internal state
handler_function const m_handler;
bool const m_can_in_place;
- result m_result;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/floppycntrl.cpp b/src/frontend/mame/ui/floppycntrl.cpp
index 72208626cb4..e820d165936 100644
--- a/src/frontend/mame/ui/floppycntrl.cpp
+++ b/src/frontend/mame/ui/floppycntrl.cpp
@@ -28,12 +28,12 @@ namespace ui {
menu_control_floppy_image::menu_control_floppy_image(mame_ui_manager &mui, render_target &target, device_image_interface &image) :
menu_control_device_image(mui, target, image),
- fd(dynamic_cast<floppy_image_device &>(image)),
- input_format(nullptr),
- output_format(nullptr),
- create_fs(nullptr),
- input_filename(),
- output_filename()
+ m_fd(dynamic_cast<floppy_image_device &>(image)),
+ m_input_format(nullptr),
+ m_output_format(nullptr),
+ m_create_fs(nullptr),
+ m_input_filename(),
+ m_output_filename()
{
}
@@ -41,183 +41,233 @@ menu_control_floppy_image::~menu_control_floppy_image()
{
}
-void menu_control_floppy_image::do_load_create()
+void menu_control_floppy_image::create_format_selected(std::string_view path, floppy_image_format_t const &format)
{
- if(input_filename.empty()) {
- auto [err, message] = fd.create(output_filename, nullptr, nullptr);
- if (err) {
- machine().popmessage(_("Error creating floppy image: %1$s"), !message.empty() ? message : err.message());
- return;
- }
- if (create_fs) {
- // HACK: ensure the floppy_image structure is created since device_image_interface may not otherwise do so during "init phase"
- err = fd.finish_load().first;
- if (!err) {
- fs::meta_data meta;
- fd.init_fs(create_fs, meta);
- }
- }
- } else {
- auto [err, message] = fd.load(input_filename);
- if (!err && !output_filename.empty()) {
- message.clear();
- err = fd.reopen_for_write(output_filename);
- }
- if (err) {
- machine().popmessage(_("Error opening floppy image: %1$s"), !message.empty() ? message : err.message());
- return;
- }
+ // get all formatable file systems
+ std::vector<std::reference_wrapper<floppy_image_device::fs_info const> > filesystems;
+ for (auto const &this_fs : m_fd.get_fs())
+ {
+ if (can_format(this_fs))
+ filesystems.emplace_back(std::ref(this_fs));
}
- if(output_format)
- fd.setup_write(output_format);
-}
-
-void menu_control_floppy_image::hook_load(const std::string &filename)
-{
- std::error_condition err;
- input_filename = filename;
- std::tie(err, input_format) = static_cast<floppy_image_device &>(m_image).identify(filename);
- if (!input_format)
+ if (filesystems.size() == 1)
{
- machine().popmessage("Error: %s", err.message());
- stack_pop();
+ stack_pop(); // pop the format selection menu
+ m_output_format = &format;
+ m_output_filename = path;
+ m_create_fs = &filesystems[0].get();
+ if (do_load_create())
+ {
+ stack_pop(); // pop the create file menu
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
}
else
{
- bool can_in_place = input_format->supports_save();
- if (can_in_place)
- {
- std::string tmp_path;
- util::core_file::ptr tmp_file;
- // attempt to open the file for writing but *without* create
- std::error_condition const filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path);
- if(!filerr)
- tmp_file.reset();
- else
- can_in_place = false;
- }
- menu::stack_push<menu_select_rw>(
+ menu::stack_push<menu_select_floppy_init>(
ui(),
target(),
- can_in_place,
- [this] (menu_select_rw::result result)
+ std::move(filesystems),
+ [this, &format, p = std::string(path)] (floppy_image_device::fs_info const &fs)
{
- switch (result)
+ stack_pop(); // pop the file system selection menu
+ stack_pop(); // pop the format selection menu
+ m_output_format = &format;
+ m_output_filename = std::move(p);
+ m_create_fs = &fs;
+ if (do_load_create())
{
- case menu_select_rw::result::READONLY:
- do_load_create();
- fd.setup_write(nullptr);
- stack_pop();
- break;
-
- case menu_select_rw::result::READWRITE:
- output_format = input_format;
- do_load_create();
- stack_pop();
- break;
-
- case menu_select_rw::result::WRITE_DIFF:
- machine().popmessage("Sorry, diffs are not supported yet\n");
- stack_pop();
- break;
-
- case menu_select_rw::result::WRITE_OTHER:
- menu::stack_push<menu_file_create>(ui(), target(), &m_image, m_current_directory, m_current_file, m_create_ok);
- m_state = CHECK_CREATE;
- break;
-
- case menu_select_rw::result::INVALID:
- m_state = START_FILE;
- break;
+ stack_pop(); // pop the create file menu
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
}
});
}
}
-bool menu_control_floppy_image::can_format(const floppy_image_device::fs_info &fs)
+void menu_control_floppy_image::output_format_selected(std::string_view path, floppy_image_format_t const &format)
{
- return !fs.m_manager || fs.m_manager->can_format();
+ stack_pop(); // pop the format selection menu
+ stack_pop(); // pop the create file menu
+ stack_pop(); // pop the access mode menu
+ m_output_filename = path;
+ m_output_format = &format;
+ m_create_fs = nullptr;
+ if (do_load_create())
+ {
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+}
+
+void menu_control_floppy_image::create_write_other(std::string const &name)
+{
+ auto path = util::zippath_combine(m_current_directory, name);
+ bool can_create, need_confirm;
+ test_create(path, can_create, need_confirm);
+ if (!can_create)
+ return;
+
+ if (need_confirm)
+ {
+ menu::stack_push<menu_confirm_save_as>(
+ ui(),
+ target(),
+ [this, path] ()
+ {
+ stack_pop(); // pop the confirm overwrite menu
+ menu::stack_push<menu_select_format>(
+ ui(),
+ target(),
+ m_fd,
+ path,
+ [this, path] (floppy_image_format_t const &format) { output_format_selected(path, format); });
+ });
+ }
+ else
+ {
+ menu::stack_push<menu_select_format>(
+ ui(),
+ target(),
+ m_fd,
+ path,
+ [this, path] (floppy_image_format_t const &format) { output_format_selected(path, format); });
+ }
}
-void menu_control_floppy_image::menu_activated()
+bool menu_control_floppy_image::do_load_create()
{
- switch (m_state) {
- case DO_CREATE: {
- std::vector<const floppy_image_format_t *> format_array;
- for(const floppy_image_format_t *i : fd.get_formats()) {
- if(!i->supports_save())
- continue;
- if (i->extension_matches(m_current_file.c_str()))
- format_array.push_back(i);
+ if (m_input_filename.empty())
+ {
+ auto [err, message] = m_fd.create(m_output_filename, nullptr, nullptr);
+ if (err)
+ {
+ machine().popmessage(_("Error creating floppy image: %1$s"), !message.empty() ? message : err.message());
+ return false;
}
- int ext_match = format_array.size();
- for(const floppy_image_format_t *i : fd.get_formats()) {
- if(!i->supports_save())
- continue;
- if (!i->extension_matches(m_current_file.c_str()))
- format_array.push_back(i);
+ if (m_create_fs)
+ {
+ // HACK: ensure the floppy_image structure is created since device_image_interface may not otherwise do so during "init phase"
+ err = m_fd.finish_load().first;
+ if (!err)
+ {
+ fs::meta_data meta;
+ m_fd.init_fs(m_create_fs, meta);
+ }
+ }
+ // TODO: what should we do if the image was created but formatting failed?
+ }
+ else
+ {
+ auto [err, message] = m_fd.load(m_input_filename);
+ if (!err && !m_output_filename.empty())
+ {
+ message.clear();
+ err = m_fd.reopen_for_write(m_output_filename);
+ // TODO: is any cleanup needed if it failed here?
}
- output_format = nullptr;
- menu::stack_push<menu_select_format>(ui(), target(), format_array, ext_match, &output_format);
+ if (err)
+ {
+ machine().popmessage(_("Error opening floppy image: %1$s"), !message.empty() ? message : err.message());
+ return false;
+ }
+ }
+ if (m_output_format)
+ m_fd.setup_write(m_output_format);
+ return true;
+}
- m_state = SELECT_FORMAT;
- break;
+bool menu_control_floppy_image::hook_load(const std::string &filename)
+{
+ m_input_filename = filename;
+ m_output_filename.clear();
+ m_output_format = nullptr;
+ std::error_condition err;
+ std::tie(err, m_input_format) = static_cast<floppy_image_device &>(m_image).identify(filename);
+ if (!m_input_format)
+ {
+ machine().popmessage(_("Error identifying image format: %1$s"), err.message());
+ return false;
}
- case SELECT_FORMAT:
- if(!output_format) {
- m_state = START_FILE;
- menu_activated();
- } else {
- // get all formatable file systems
- std::vector<std::reference_wrapper<const floppy_image_device::fs_info>> fs;
- for (const auto &this_fs : fd.get_fs()) {
- if (can_format(this_fs))
- fs.emplace_back(std::ref(this_fs));
- }
+ bool can_in_place = m_input_format->supports_save();
+ if (can_in_place)
+ {
+ std::string tmp_path;
+ util::core_file::ptr tmp_file;
+ // attempt to open the file for writing but *without* create
+ std::error_condition const filerr = util::zippath_fopen(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path);
+ if (filerr)
+ can_in_place = false;
+ }
- output_filename = util::zippath_combine(m_current_directory, m_current_file);
- if(fs.size() == 1) {
- create_fs = &(fs[0].get());
- do_load_create();
- stack_pop();
- } else {
- m_submenu_result.i = -1;
- menu::stack_push<menu_select_floppy_init>(ui(), target(), std::move(fs), &m_submenu_result.i);
- m_state = SELECT_INIT;
- }
- }
- break;
-
- case SELECT_INIT:
- // figure out which (if any) create file system was selected
- create_fs = nullptr;
- if(m_submenu_result.i >= 0) {
- int i = 0;
- for (const auto &this_fs : fd.get_fs()) {
- if (can_format(this_fs)) {
- if (i == m_submenu_result.i) {
- create_fs = &this_fs;
- break;
+ menu::stack_push<menu_select_rw>(
+ ui(),
+ target(),
+ can_in_place,
+ [this] (menu_select_rw::result result)
+ {
+ switch (result)
+ {
+ case menu_select_rw::result::READONLY:
+ {
+ stack_pop(); // pop the access mode menu
+ bool const result = do_load_create();
+ m_fd.setup_write(nullptr);
+ if (result)
+ {
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
}
- i++;
+ break;
+
+ case menu_select_rw::result::READWRITE:
+ stack_pop(); // pop the access mode menu
+ m_output_format = m_input_format;
+ if (do_load_create())
+ {
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ break;
+
+ case menu_select_rw::result::WRITE_DIFF:
+ machine().popmessage(_("Sorry, diffs are not supported yet."));
+ break;
+
+ case menu_select_rw::result::WRITE_OTHER:
+ menu::stack_push<menu_file_create>(
+ ui(), target(),
+ m_image,
+ m_current_directory,
+ std::string(),
+ [this] (std::string const &name) { create_write_other(name); });
+ break;
}
- }
- }
+ });
+ return false;
+}
- if(!create_fs) {
- m_state = START_FILE;
- menu_activated();
- } else {
- do_load_create();
- stack_pop();
- }
- break;
+bool menu_control_floppy_image::hook_create(std::string_view path)
+{
+ m_input_format = nullptr;
+ m_input_filename.clear();
+ menu::stack_push<menu_select_format>(
+ ui(),
+ target(),
+ m_fd,
+ path,
+ [this, p = std::string(path)] (floppy_image_format_t const &format) { create_format_selected(p, format); });
- default:
- menu_control_device_image::menu_activated();
- }
+ return false;
+}
+
+bool menu_control_floppy_image::can_format(floppy_image_device::fs_info const &fs)
+{
+ return !fs.m_manager || fs.m_manager->can_format();
}
} // namespace ui
diff --git a/src/frontend/mame/ui/floppycntrl.h b/src/frontend/mame/ui/floppycntrl.h
index 8ff0baab814..36811cc1c9a 100644
--- a/src/frontend/mame/ui/floppycntrl.h
+++ b/src/frontend/mame/ui/floppycntrl.h
@@ -15,6 +15,8 @@
#include "imagedev/floppy.h"
#include <memory>
+#include <string>
+#include <string_view>
namespace ui {
@@ -25,19 +27,20 @@ public:
menu_control_floppy_image(mame_ui_manager &ui, render_target &target, device_image_interface &image);
virtual ~menu_control_floppy_image() override;
-protected:
- virtual void menu_activated() override;
-
private:
- enum { SELECT_FORMAT = LAST_ID, SELECT_MEDIA, SELECT_INIT };
+ floppy_image_device &m_fd;
+ const floppy_image_format_t *m_input_format, *m_output_format;
+ const floppy_image_device::fs_info *m_create_fs;
+ std::string m_input_filename, m_output_filename;
+
+ virtual bool hook_load(const std::string &filename) override;
+ virtual bool hook_create(std::string_view path) override;
- floppy_image_device &fd;
- const floppy_image_format_t *input_format, *output_format;
- const floppy_image_device::fs_info *create_fs;
- std::string input_filename, output_filename;
+ void create_format_selected(std::string_view path, floppy_image_format_t const &format);
+ void output_format_selected(std::string_view path, floppy_image_format_t const &format);
+ void create_write_other(std::string const &name);
+ bool do_load_create();
- void do_load_create();
- virtual void hook_load(const std::string &filename) override;
static bool can_format(const floppy_image_device::fs_info &fs);
};
diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp
index 5aa6ae2579f..b236ff40765 100644
--- a/src/frontend/mame/ui/imgcntrl.cpp
+++ b/src/frontend/mame/ui/imgcntrl.cpp
@@ -26,6 +26,7 @@
#include "image.h"
#include "softlist_dev.h"
+#include "util/path.h"
#include "util/zippath.h"
@@ -42,14 +43,10 @@ namespace ui {
menu_control_device_image::menu_control_device_image(mame_ui_manager &mui, render_target &target, device_image_interface &image)
: menu(mui, target)
, m_image(image)
- , m_create_ok(false)
- , m_create_confirmed(false)
, m_swi(nullptr)
, m_swp(nullptr)
, m_sld(nullptr)
{
- m_submenu_result.i = -1;
-
if (m_image.software_list_name())
m_sld = software_list_device::find_by_name(mui.machine().config(), m_image.software_list_name());
m_swi = m_image.software_entry();
@@ -134,19 +131,16 @@ menu_control_device_image::~menu_control_device_image()
//-------------------------------------------------
-// test_create - creates a new disk image
+// test_create
//-------------------------------------------------
-void menu_control_device_image::test_create(bool &can_create, bool &need_confirm)
+void menu_control_device_image::test_create(std::string const &path, bool &can_create, bool &need_confirm)
{
- // assemble the full path
- auto path = util::zippath_combine(m_current_directory, m_current_file);
-
// does a file or a directory exist at the path
auto entry = osd_stat(path);
auto file_type = (entry != nullptr) ? entry->type : osd::directory::entry::entry_type::NONE;
- switch(file_type)
+ switch (file_type)
{
case osd::directory::entry::entry_type::NONE:
// no file/dir here - always create
@@ -176,266 +170,352 @@ void menu_control_device_image::test_create(bool &can_create, bool &need_confirm
//-------------------------------------------------
-// load_software_part
+// hook_load
//-------------------------------------------------
-void menu_control_device_image::load_software_part()
+bool menu_control_device_image::hook_load(std::string const &name)
{
- std::string temp_name = string_format("%s:%s:%s", m_sld->list_name(), m_swi->shortname(), m_swp->name());
-
- driver_enumerator drivlist(machine().options(), machine().options().system_name());
- drivlist.next();
- media_auditor auditor(drivlist);
- media_auditor::summary summary = auditor.audit_software(*m_sld, *m_swi, AUDIT_VALIDATE_FAST);
- // if everything looks good, load software
- if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
+ auto [err, msg] = m_image.load(name);
+ if (err)
{
- auto [err, msg] = m_image.load_software(temp_name);
- if (err)
- machine().popmessage(_("Error loading software item: %1$s"), !msg.empty() ? msg : err.message());
- stack_pop();
+ machine().popmessage(_("Error loading media image: %1$s"), !msg.empty() ? msg : err.message());
+ return false;
}
else
{
- machine().popmessage(_("Files required for the selected software are missing or incorrect."));
- m_state = SELECT_SOFTLIST;
- menu_activated();
+ return true;
}
}
//-------------------------------------------------
-// hook_load
+// hook_create
//-------------------------------------------------
-void menu_control_device_image::hook_load(const std::string &name)
+bool menu_control_device_image::hook_create(std::string_view path)
{
- auto [err, msg] = m_image.load(name);
- if (err)
- machine().popmessage(_("Error loading media image: %1$s"), !msg.empty() ? msg : err.message());
- stack_pop();
+ auto [err, msg] = m_image.create(path, nullptr, nullptr);
+ if (!err)
+ return true;
+
+ machine().popmessage(_("Error creating media image: %1$s"), !msg.empty() ? msg : err.message());
+ return false;
}
//-------------------------------------------------
-// populate
+// start_file
//-------------------------------------------------
-void menu_control_device_image::populate()
+void menu_control_device_image::start_file()
{
- throw emu_fatalerror("menu_control_device_image::populate: Shouldn't get here!");
+ menu::stack_push<menu_file_selector>(
+ ui(), target(),
+ m_image,
+ m_current_directory,
+ m_current_file,
+ true,
+ m_image.image_interface() != nullptr,
+ m_image.is_creatable(),
+ [this] (menu_file_selector::result result, std::string const &directory, std::string const &file)
+ {
+ m_current_directory = directory;
+ m_current_file = file;
+ switch (result)
+ {
+ case menu_file_selector::result::EMPTY:
+ m_image.unload();
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ break;
+
+ case menu_file_selector::result::FILE:
+ if (hook_load(file))
+ {
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ break;
+
+ case menu_file_selector::result::CREATE:
+ menu::stack_push<menu_file_create>(
+ ui(),
+ target(),
+ m_image,
+ directory,
+ std::string(core_filename_extract_base(m_current_file)),
+ [this] (std::string const &name) { create_file(m_current_directory, name); });
+ break;
+
+ case menu_file_selector::result::SOFTLIST:
+ stack_pop(); // pop the file selection menu
+ start_softlist();
+ break;
+
+ case menu_file_selector::result::MIDI:
+ stack_pop(); // pop the file selection menu
+ start_midi();
+ break;
+ }
+ });
}
//-------------------------------------------------
-// handle
+// start_softlist
//-------------------------------------------------
-bool menu_control_device_image::handle(event const *ev)
+void menu_control_device_image::start_softlist()
{
- throw emu_fatalerror("menu_control_device_image::handle: Shouldn't get here!");
+ menu::stack_push<menu_software>(
+ ui(),
+ target(),
+ m_image.image_interface(),
+ [this] (software_list_device *sld)
+ {
+ if (!sld)
+ {
+ stack_pop(); // pop the software lists menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ else
+ {
+ menu::stack_push<menu_software_list>(
+ ui(),
+ target(),
+ *sld,
+ m_image.image_interface(),
+ [this, sld] (std::string_view item) { software_item_selected(*sld, item); });
+ }
+ });
}
//-------------------------------------------------
-// menu_activated
+// start_midi
//-------------------------------------------------
-void menu_control_device_image::menu_activated()
+void menu_control_device_image::start_midi()
{
- switch(m_state)
- {
- case START_FILE:
- menu::stack_push<menu_file_selector>(
- ui(), target(),
- &m_image,
- m_current_directory,
- m_current_file,
- true,
- m_image.image_interface() != nullptr,
- m_image.is_creatable(),
- [this] (menu_file_selector::result result, std::string &&directory, std::string &&file)
+ menu::stack_push<menu_midi_inout>(
+ ui(),
+ target(),
+ m_image.device().type() == MIDIIN,
+ [this] (std::string const &port)
+ {
+ auto const [err, msg] = m_image.load(port);
+ if (err)
{
- m_current_directory = std::move(directory);
- m_current_file = std::move(file);
- switch (result)
- {
- case menu_file_selector::result::EMPTY:
- m_image.unload();
- stack_pop();
- break;
+ machine().popmessage(_("Error opening MIDI port: %1$s"), !msg.empty() ? msg : err.message());
+ }
+ else
+ {
+ stack_pop(); // pop the MIDI port selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ });
+}
- case menu_file_selector::result::FILE:
- hook_load(m_current_file);
- break;
- case menu_file_selector::result::CREATE:
- menu::stack_push<menu_file_create>(ui(), target(), &m_image, m_current_directory, m_current_file, m_create_ok);
- m_state = CHECK_CREATE;
- break;
+//-------------------------------------------------
+// load_software_part
+//-------------------------------------------------
- case menu_file_selector::result::SOFTLIST:
- m_state = START_SOFTLIST;
- break;
+bool menu_control_device_image::load_software_part(software_list_device &sld, software_info const &swi, software_part const &swp)
+{
+ std::string temp_name = string_format("%s:%s:%s", sld.list_name(), swi.shortname(), swp.name());
- case menu_file_selector::result::MIDI:
- m_state = START_MIDI;
- break;
+ driver_enumerator drivlist(machine().options(), machine().options().system_name());
+ drivlist.next();
+ media_auditor auditor(drivlist);
+ media_auditor::summary summary = auditor.audit_software(sld, swi, AUDIT_VALIDATE_FAST);
- default: // return to system
- stack_pop();
- break;
+ // if everything looks good, load software
+ if ((summary == media_auditor::CORRECT) || (summary == media_auditor::BEST_AVAILABLE) || (summary == media_auditor::NONE_NEEDED))
+ {
+ auto [err, msg] = m_image.load_software(temp_name);
+ if (!err)
+ return true;
+
+ machine().popmessage(_("Error loading software item: %1$s"), !msg.empty() ? msg : err.message());
+ return false;
+ }
+ else
+ {
+ machine().popmessage(_("Files required for the selected software are missing or incorrect."));
+ return false;
+ }
+}
+
+
+//-------------------------------------------------
+// software_item_selected
+//-------------------------------------------------
+
+void menu_control_device_image::software_item_selected(software_list_device &sld, std::string_view item)
+{
+ auto *const swi = sld.find(item);
+ assert(swi);
+
+ if (swi->has_multiple_parts(m_image.image_interface()))
+ {
+ menu::stack_push<menu_software_parts>(
+ ui(),
+ target(),
+ *swi,
+ m_image.image_interface(),
+ false,
+ [this, &sld, swi] (menu_software_parts::result action, software_part const *swp)
+ {
+ assert(menu_software_parts::result::ENTRY == action);
+ assert(swp);
+
+ if (load_software_part(sld, *swi, *swp))
+ {
+ stack_pop(); // pop the software parts menu
+ stack_pop(); // pop the software items menu
+ stack_pop(); // pop the software lists menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
}
});
- break;
+ }
+ else
+ {
+ auto *const swp = swi->find_part("", m_image.image_interface());
+ assert(swp);
- case START_SOFTLIST:
- m_sld = nullptr;
- menu::stack_push<menu_software>(ui(), target(), m_image.image_interface(), &m_sld);
- m_state = SELECT_SOFTLIST;
- break;
+ if (load_software_part(sld, *swi, *swp))
+ {
+ stack_pop(); // pop the software items menu
+ stack_pop(); // pop the software lists menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ }
+}
- case START_MIDI:
- m_midi = "";
- menu::stack_push<menu_midi_inout>(ui(), target(), m_image.device().type() == MIDIIN, &m_midi);
- m_state = SELECT_MIDI;
- break;
- case SELECT_MIDI:
- if(!m_midi.empty())
+//-------------------------------------------------
+// other_part_selected
+//-------------------------------------------------
+
+void menu_control_device_image::other_part_selected(menu_software_parts::result action, software_part const *swp)
+{
+ switch (action)
+ {
+ case menu_software_parts::result::ENTRY:
+ assert(swp);
+ if (load_software_part(*m_sld, *m_swi, *swp))
{
- auto [err, msg] = m_image.load(m_midi);
- if (err)
- machine().popmessage(_("Error connecting to midi port: %1$s"), !msg.empty() ? msg : err.message());
+ stack_pop(); // pop the software parts menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
}
- stack_pop();
break;
- case START_OTHER_PART:
- m_submenu_result.swparts = menu_software_parts::result::INVALID;
- menu::stack_push<menu_software_parts>(ui(), target(), m_swi, m_image.image_interface(), &m_swp, true, m_submenu_result.swparts);
- m_state = SELECT_OTHER_PART;
+ case menu_software_parts::result::FMGR:
+ stack_pop(); // pop the software parts menu
+ start_file();
break;
- case SELECT_SOFTLIST:
- if (!m_sld)
- {
- stack_pop();
- }
- else
- {
- m_software_info_name.clear();
- menu::stack_push<menu_software_list>(ui(), target(), m_sld, m_image.image_interface(), m_software_info_name);
- m_state = SELECT_PARTLIST;
- }
+ case menu_software_parts::result::EMPTY:
+ m_image.unload();
+ stack_pop(); // pop the software parts menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
break;
- case SELECT_PARTLIST:
- m_swi = m_sld->find(m_software_info_name);
- if (!m_swi)
- {
- m_state = START_SOFTLIST;
- menu_activated();
- }
- else if (m_swi->has_multiple_parts(m_image.image_interface()))
- {
- m_submenu_result.swparts = menu_software_parts::result::INVALID;
- m_swp = nullptr;
- menu::stack_push<menu_software_parts>(ui(), target(), m_swi, m_image.image_interface(), &m_swp, false, m_submenu_result.swparts);
- m_state = SELECT_ONE_PART;
- }
- else
- {
- m_swp = m_swi->find_part("", m_image.image_interface());
- load_software_part();
- }
+ case menu_software_parts::result::SWLIST:
+ stack_pop(); // pop the software parts menu
+ start_softlist();
break;
+ }
+}
- case SELECT_ONE_PART:
- switch (m_submenu_result.swparts)
- {
- case menu_software_parts::result::ENTRY:
- load_software_part();
- break;
- default: // return to list
- m_state = SELECT_SOFTLIST;
- menu_activated();
- break;
- }
- break;
+//-------------------------------------------------
+// create_file
+//-------------------------------------------------
+
+void menu_control_device_image::create_file(std::string const &directory, std::string const &name)
+{
+ auto path = util::zippath_combine(directory, name);
+ bool can_create, need_confirm;
+ test_create(path, can_create, need_confirm);
+ if (!can_create)
+ return;
- case SELECT_OTHER_PART:
- switch (m_submenu_result.swparts)
+ if (need_confirm)
+ {
+ menu::stack_push<menu_confirm_save_as>(
+ ui(),
+ target(),
+ [this, path] ()
+ {
+ stack_pop(); // pop the confirm overwrite menu
+ if (hook_create(path))
+ {
+ stack_pop(); // pop the create file menu
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ });
+ }
+ else
+ {
+ if (hook_create(path))
{
- case menu_software_parts::result::ENTRY:
- load_software_part();
- break;
+ stack_pop(); // pop the create file menu
+ stack_pop(); // pop the file selection menu
+ stack_pop(); // pop the fake menu that orchestrates the other menus
+ }
+ }
+}
- case menu_software_parts::result::FMGR:
- m_state = START_FILE;
- menu_activated();
- break;
- case menu_software_parts::result::EMPTY:
- m_image.unload();
- stack_pop();
- break;
+//-------------------------------------------------
+// populate
+//-------------------------------------------------
- case menu_software_parts::result::SWLIST:
- m_state = START_SOFTLIST;
- menu_activated();
- break;
+void menu_control_device_image::populate()
+{
+ throw emu_fatalerror("menu_control_device_image::populate: Shouldn't get here!");
+}
- case menu_software_parts::result::INVALID: // return to system
- stack_pop();
- break;
- }
- break;
- case CREATE_FILE:
- {
- bool can_create, need_confirm;
- test_create(can_create, need_confirm);
- if (can_create)
- {
- if (need_confirm)
- {
- menu::stack_push<menu_confirm_save_as>(ui(), target(), m_create_confirmed);
- m_state = CREATE_CONFIRM;
- }
- else
- {
- m_state = DO_CREATE;
- menu_activated();
- }
- }
- else
- {
- m_state = START_FILE;
- menu_activated();
- }
- }
- break;
+//-------------------------------------------------
+// handle
+//-------------------------------------------------
+
+bool menu_control_device_image::handle(event const *ev)
+{
+ throw emu_fatalerror("menu_control_device_image::handle: Shouldn't get here!");
+}
+
+
+//-------------------------------------------------
+// menu_activated
+//-------------------------------------------------
- case CREATE_CONFIRM:
- m_state = m_create_confirmed ? DO_CREATE : START_FILE;
- menu_activated();
+void menu_control_device_image::menu_activated()
+{
+ switch (m_state)
+ {
+ case START_FILE:
+ start_file();
+ m_state = DONE;
break;
- case CHECK_CREATE:
- m_state = m_create_ok ? CREATE_FILE : START_FILE;
- menu_activated();
+ case START_OTHER_PART:
+ menu::stack_push<menu_software_parts>(
+ ui(),
+ target(),
+ *m_swi,
+ m_image.image_interface(),
+ true,
+ [this] (menu_software_parts::result action, software_part const *swp) { other_part_selected(action, swp); });
+ m_state = DONE;
break;
- case DO_CREATE:
- {
- auto path = util::zippath_combine(m_current_directory, m_current_file);
- auto [err, msg] = m_image.create(path, nullptr, nullptr);
- if (err)
- machine().popmessage(_("Error creating media image: %1$s"), !msg.empty() ? msg : err.message());
- stack_pop();
- }
+ case DONE:
+ stack_pop();
break;
}
}
diff --git a/src/frontend/mame/ui/imgcntrl.h b/src/frontend/mame/ui/imgcntrl.h
index eb24e1856ca..7fadb1907cd 100644
--- a/src/frontend/mame/ui/imgcntrl.h
+++ b/src/frontend/mame/ui/imgcntrl.h
@@ -26,47 +26,42 @@ public:
virtual ~menu_control_device_image() override;
protected:
- enum
- {
- START_FILE, START_OTHER_PART, START_SOFTLIST, START_MIDI,
- SELECT_PARTLIST, SELECT_ONE_PART, SELECT_OTHER_PART,
- CREATE_FILE, CREATE_CONFIRM, CHECK_CREATE, DO_CREATE, SELECT_SOFTLIST, SELECT_MIDI,
- LAST_ID
- };
-
- // this is a single union that contains all of the different types of
- // results we could get from child menus
- union
- {
- menu_software_parts::result swparts;
- int i;
- } m_submenu_result;
-
// instance variables - made protected so they can be shared with floppycntrl.cpp
- int m_state;
device_image_interface & m_image;
std::string m_current_directory;
std::string m_current_file;
- bool m_create_ok;
// methods
virtual void menu_activated() override;
virtual bool handle(event const *ev) override;
- virtual void hook_load(const std::string &filename);
+
+ virtual void create_file(std::string const &directory, std::string const &name);
+ void test_create(std::string const &path, bool &can_create, bool &need_confirm);
private:
+ enum
+ {
+ START_FILE, START_OTHER_PART, DONE
+ };
+
// instance variables
- bool m_create_confirmed;
+ int m_state;
const software_info * m_swi;
const software_part * m_swp;
class software_list_device * m_sld;
- std::string m_software_info_name;
- std::string m_midi;
// methods
virtual void populate() override;
- void test_create(bool &can_create, bool &need_confirm);
- void load_software_part();
+
+ virtual bool hook_load(std::string const &filename);
+ virtual bool hook_create(std::string_view path);
+
+ void start_file();
+ void start_softlist();
+ void start_midi();
+ bool load_software_part(software_list_device &sld, software_info const &swi, software_part const &swp);
+ void software_item_selected(software_list_device &sld, std::string_view item);
+ void other_part_selected(menu_software_parts::result action, software_part const *swp);
};
} // namespace ui
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index 734187327fb..52a538d20d6 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -652,6 +652,12 @@ std::string machine_info::get_screen_desc(screen_device &screen) const
menu_game_info::menu_game_info(mame_ui_manager &mui, render_target &target) : menu_textbox(mui, target)
{
set_process_flags(PROCESS_CUSTOM_NAV);
+
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
+ {
+ if (image.user_loadable() || image.has_preset_images_selection())
+ m_notifiers.emplace_back(image.add_media_change_notifier(delegate(&menu_game_info::reload, this)));
+ }
}
menu_game_info::~menu_game_info()
@@ -670,7 +676,85 @@ void menu_game_info::populate_text(std::optional<text_layout> &layout, float &wi
{
rgb_t const color = ui().colors().text_color();
layout.emplace(create_layout(width));
+
+ // add the system info text
layout->add_text(ui().machine_info().game_info_string(), color);
+
+ // add media information
+ std::ostringstream mediainfo;
+ device_t *prev_parent = nullptr;
+ for (device_t &parent : device_enumerator(machine().root_device()))
+ {
+ for (device_image_interface &image : image_interface_enumerator(parent, 1))
+ {
+ if ((&image.device() != &parent) && (image.user_loadable() || image.has_preset_images_selection()))
+ {
+ if (&parent != prev_parent)
+ {
+ prev_parent = &parent;
+ util::stream_format(mediainfo, _("\nMedia: [root%1$s]\n"), parent.tag());
+ }
+ if (image.user_loadable())
+ {
+ if (!image.exists())
+ {
+ util::stream_format( mediainfo, _("%1$s (%2$s): [no media]\n"),
+ image.instance_name(),
+ image.brief_instance_name());
+ }
+ else if (!image.loaded_through_softlist())
+ {
+ util::stream_format(mediainfo, _("%1$s (%2$s): %3$s\n"),
+ image.instance_name(),
+ image.brief_instance_name(),
+ image.filename());
+ }
+ else
+ {
+ software_info const &swinfo(*image.software_entry());
+ auto const partid = image.get_feature("part_id");
+ char const *fmt;
+ if (partid)
+ {
+ if (swinfo.supported() == software_support::UNSUPPORTED)
+ fmt = _("%1$s (%2$s): %3$s:%4$s %5$s (not supported)\n%6$s\n%7$s, %8$s\n");
+ else if (swinfo.supported() == software_support::UNSUPPORTED)
+ fmt = _("%1$s (%2$s): %3$s:%4$s %5$s (partially supported)\n%6$s\n%7$s, %8$s\n");
+ else
+ fmt = _("%1$s (%2$s): %3$s:%4$s %5$s\n%6$s\n%7$s, %8$s\n");
+ }
+ else
+ {
+ if (swinfo.supported() == software_support::UNSUPPORTED)
+ fmt = _("%1$s (%2$s): %3$s:%4$s (not supported)\n%6$s\n%7$s, %8$s\n");
+ else if (swinfo.supported() == software_support::UNSUPPORTED)
+ fmt = _("%1$s (%2$s): %3$s:%4$s (partially supported)\n%6$s\n%7$s, %8$s\n");
+ else
+ fmt = _("%1$s (%2$s): %3$s:%4$s\n%6$s\n%7$s, %8$s\n");
+ }
+ util::stream_format(mediainfo, fmt,
+ image.instance_name(),
+ image.brief_instance_name(),
+ image.basename(),
+ image.part_entry()->name(),
+ partid,
+ swinfo.longname(),
+ swinfo.publisher(),
+ swinfo.year());
+ }
+ }
+ else if (image.has_preset_images_selection())
+ {
+ util::stream_format(mediainfo, _("%1$s (%2$s preset %u)\n"),
+ image.preset_images_list()[image.current_preset_image_id()],
+ image.filename(),
+ image.current_preset_image_id() + 1);
+ }
+ }
+ }
+ }
+ layout->add_text(std::move(mediainfo).str(), color);
+
lines = layout->lines();
}
width = layout->actual_width();
@@ -680,6 +764,11 @@ void menu_game_info::populate()
{
}
+void menu_game_info::reload(device_image_interface::media_change_event ev)
+{
+ reset_layout();
+}
+
/*-------------------------------------------------
menu_warn_info - handle the emulation warnings menu
@@ -739,93 +828,4 @@ void menu_warn_info::populate()
{
}
-
-/*-------------------------------------------------
- menu_image_info - handle the image information menu
--------------------------------------------------*/
-
-menu_image_info::menu_image_info(mame_ui_manager &mui, render_target &target) : menu(mui, target)
-{
- set_heading(_("Media Image Information"));
-}
-
-menu_image_info::~menu_image_info()
-{
-}
-
-void menu_image_info::menu_activated()
-{
- reset(reset_options::REMEMBER_POSITION);
-}
-
-void menu_image_info::populate()
-{
- for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
- image_info(image);
-}
-
-bool menu_image_info::handle(event const *ev)
-{
- return false;
-}
-
-
-/*-------------------------------------------------
- image_info - display image info for a specific
- image interface device
--------------------------------------------------*/
-
-void menu_image_info::image_info(device_image_interface &image)
-{
- if (!image.user_loadable())
- return;
-
- m_notifiers.emplace_back(image.add_media_change_notifier(delegate(&menu_image_info::reload, this)));
-
- if (image.exists())
- {
- // display device type and filename
- item_append(image.brief_instance_name(), image.basename(), 0, &image);
-
- // if image has been loaded through softlist, let's add some more info
- if (image.loaded_through_softlist())
- {
- software_info const &swinfo(*image.software_entry());
-
- // display full name, publisher and year
- item_append(swinfo.longname(), FLAG_DISABLE, nullptr);
- item_append(string_format("%1$s, %2$s", swinfo.publisher(), swinfo.year()), FLAG_DISABLE, nullptr);
-
- // display supported information, if available
- switch (swinfo.supported())
- {
- case software_support::UNSUPPORTED:
- item_append(_("Not supported"), FLAG_DISABLE, nullptr);
- break;
- case software_support::PARTIALLY_SUPPORTED:
- item_append(_("Partially supported"), FLAG_DISABLE, nullptr);
- break;
- case software_support::SUPPORTED:
- break;
- }
- }
- }
- else
- {
- item_append(image.brief_instance_name(), _("[empty]"), 0, &image);
- }
- item_append(menu_item_type::SEPARATOR);
-}
-
-
-/*-------------------------------------------------
- reload - refresh the menu after a media change
--------------------------------------------------*/
-
-void menu_image_info::reload(device_image_interface::media_change_event ev)
-{
- m_notifiers.clear();
- reset(reset_options::REMEMBER_REF);
-}
-
} // namespace ui
diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h
index a289fc9f9dd..2d20dd26fc8 100644
--- a/src/frontend/mame/ui/info.h
+++ b/src/frontend/mame/ui/info.h
@@ -112,6 +112,10 @@ protected:
private:
virtual void populate() override;
+
+ void reload(device_image_interface::media_change_event ev);
+
+ std::vector<util::notifier_subscription> m_notifiers;
};
@@ -128,25 +132,6 @@ private:
virtual void populate() override;
};
-
-class menu_image_info : public menu
-{
-public:
- menu_image_info(mame_ui_manager &mui, render_target &target);
- virtual ~menu_image_info() override;
-
-protected:
- virtual void menu_activated() override;
-
-private:
- virtual void populate() override;
- virtual bool handle(event const *ev) override;
- void image_info(device_image_interface &image);
- void reload(device_image_interface::media_change_event ev);
-
- std::vector<util::notifier_subscription> m_notifiers;
-};
-
} // namespace ui
#endif // MAME_FRONTEND_UI_INFO_H
diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp
index 9a7ad400995..391a91d34eb 100644
--- a/src/frontend/mame/ui/mainmenu.cpp
+++ b/src/frontend/mame/ui/mainmenu.cpp
@@ -53,7 +53,6 @@ enum : unsigned {
BOOKKEEPING,
GAME_INFO,
WARN_INFO,
- IMAGE_MENU_IMAGE_INFO,
IMAGE_MENU_FILE_MANAGER,
TAPE_CONTROL,
SLOT_DEVICES,
@@ -130,18 +129,13 @@ void menu_main::populate()
item_append(_("menu-main", "Warning Information"), 0, (void *)WARN_INFO);
for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
- if (image.user_loadable())
- {
- item_append(_("menu-main", "Media Image Information"), 0, (void *)IMAGE_MENU_IMAGE_INFO);
- break;
- }
-
- for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
+ {
if (image.user_loadable() || image.has_preset_images_selection())
{
- item_append(_("menu-main", "File Manager"), 0, (void *)IMAGE_MENU_FILE_MANAGER);
+ item_append(_("menu-main", "Media Control"), 0, (void *)IMAGE_MENU_FILE_MANAGER);
break;
}
+ }
if (cassette_device_enumerator(machine().root_device()).first() != nullptr)
item_append(_("menu-main", "Tape Control"), 0, (void *)TAPE_CONTROL);
@@ -251,10 +245,6 @@ bool menu_main::handle(event const *ev)
menu::stack_push<menu_warn_info>(ui(), target());
break;
- case IMAGE_MENU_IMAGE_INFO:
- menu::stack_push<menu_image_info>(ui(), target());
- break;
-
case IMAGE_MENU_FILE_MANAGER:
menu::stack_push<menu_file_manager>(ui(), target(), std::string());
break;
diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp
index da42c25a531..80776617104 100644
--- a/src/frontend/mame/ui/menu.cpp
+++ b/src/frontend/mame/ui/menu.cpp
@@ -615,7 +615,7 @@ void menu::draw(uint32_t flags)
// compute the width and height of the full menu
float visible_width = 0;
- float visible_main_menu_height = 0;
+ float visible_main_menu_height = line_height() * m_items.size();
for (auto const &pitem : m_items)
{
// compute width of left hand side
@@ -629,9 +629,6 @@ void menu::draw(uint32_t flags)
// track the maximum
visible_width = std::max(total_width, visible_width);
-
- // track the height as well
- visible_main_menu_height += line_height();
}
// lay out the heading if present
@@ -755,6 +752,7 @@ void menu::draw(uint32_t flags)
// work out what we're dealing with
bool const uparrow = !linenum && m_show_up_arrow;
bool const downarrow = (linenum == (m_visible_lines - 1)) && m_show_down_arrow;
+ bool const hovered = have_pointer() && pointer_in_rect(m_items_left, line_y0, m_items_right, line_y1);
// highlight if necessary
if (is_selected(itemnum))
@@ -772,7 +770,7 @@ void menu::draw(uint32_t flags)
fgcolor = fgcolor2 = fgcolor3 = ui().colors().mouseover_color();
bgcolor = ui().colors().mouseover_bg_color();
}
- else if (have_pointer() && pointer_in_rect(m_items_left, line_y0, m_items_right, line_y1))
+ else if (hovered)
{
if ((track_pointer::TRACK_LINE == m_pointer_state) && pointerline)
{
@@ -899,21 +897,31 @@ void menu::draw(uint32_t flags)
}
// apply arrows
- if (is_selected(itemnum) && (pitem.flags() & (FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW)))
+ bool const adjustarrows = is_selectable(pitem) && (pitem.flags() & (FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW));
+ if (adjustarrows && (is_selected(itemnum) || (hovered && (track_pointer::IDLE == m_pointer_state))))
{
- m_adjust_top = line_y0 + (0.1F * line_height());
- m_adjust_bottom = line_y0 + (0.9F * line_height());
+ float const t = line_y0 + (0.1F * line_height());
+ float const b = line_y0 + (0.9F * line_height());
+ if (hovered)
+ {
+ m_adjust_top = t;
+ m_adjust_bottom = b;
+ }
if (pitem.flags() & FLAG_LEFT_ARROW)
{
- m_decrease_left = effective_left + effective_width - subitem_width - gutter_width();
- float const r = m_decrease_left + lr_arrow_width();
- draw_arrow(m_decrease_left, m_adjust_top, r, m_adjust_bottom, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
+ float const l = effective_left + effective_width - subitem_width - gutter_width();
+ float const r = l + lr_arrow_width();
+ draw_arrow(l, t, r, b, fgcolor, ROT90 ^ ORIENTATION_FLIP_X);
+ if (hovered)
+ m_decrease_left = l;
}
if (pitem.flags() & FLAG_RIGHT_ARROW)
{
float const r = effective_left + effective_width + gutter_width();
- m_increase_left = r - lr_arrow_width();
- draw_arrow(m_increase_left, m_adjust_top, r, m_adjust_bottom, fgcolor, ROT90);
+ float const l = r - lr_arrow_width();
+ draw_arrow(l, t, r, b, fgcolor, ROT90);
+ if (hovered)
+ m_increase_left = l;
}
}
}
@@ -1357,13 +1365,23 @@ std::pair<int, bool> menu::handle_primary_down(uint32_t flags, ui_event const &u
// FIXME: should repeat if appropriate
if (!is_touch && (y >= m_adjust_top) && (y < m_adjust_bottom))
{
+ // work out which line/item it is
+ auto const lineno(int((y - m_items_top) / line_height()));
+ int const itemno(lineno + top_line);
+ assert(lineno >= 0);
+ assert(lineno < m_visible_lines);
+ assert(itemno < m_items.size());
+ assert(is_selectable(m_items[itemno]));
+
if ((x >= m_decrease_left) && (x < (m_decrease_left + lr_arrow_width())))
{
+ m_selected = itemno;
m_pointer_state = track_pointer::COMPLETED;
return std::make_pair(IPT_UI_LEFT, false);
}
else if ((x >= m_increase_left) && (x < (m_increase_left + lr_arrow_width())))
{
+ m_selected = itemno;
m_pointer_state = track_pointer::COMPLETED;
return std::make_pair(IPT_UI_RIGHT, false);
}
diff --git a/src/frontend/mame/ui/midiinout.cpp b/src/frontend/mame/ui/midiinout.cpp
index 387f66b3e57..a5edd55f5a8 100644
--- a/src/frontend/mame/ui/midiinout.cpp
+++ b/src/frontend/mame/ui/midiinout.cpp
@@ -17,12 +17,16 @@
namespace ui {
-menu_midi_inout::menu_midi_inout(mame_ui_manager &mui, render_target &target, bool is_input, std::string *channel)
+menu_midi_inout::menu_midi_inout(
+ mame_ui_manager &mui,
+ render_target &target,
+ bool is_input,
+ handler_function &&handler)
: menu(mui, target)
- , m_channel(channel)
+ , m_handler(std::move(handler))
, m_is_input(is_input)
{
- set_heading(m_is_input ? _("MIDI input channel") : _("MIDI output channel"));
+ set_heading(m_is_input ? _("menu-midiport", "MIDI input port") : _("menu-midiport", "MIDI output port"));
}
menu_midi_inout::~menu_midi_inout()
@@ -31,14 +35,11 @@ menu_midi_inout::~menu_midi_inout()
bool menu_midi_inout::handle(event const *ev)
{
- if(!ev)
+ if (!ev)
return false;
- if(ev->iptkey == IPT_UI_SELECT) {
- *m_channel = m_port_names[uintptr_t(ev->itemref)];
- stack_pop();
- return true;
- }
+ if (ev->iptkey == IPT_UI_SELECT)
+ m_handler(m_port_names[uintptr_t(ev->itemref)]);
return false;
}
@@ -51,53 +52,27 @@ bool menu_midi_inout::handle(event const *ev)
void menu_midi_inout::populate()
{
- auto ports = machine().osd().list_midi_ports();
- for(auto &p : ports)
- if((m_is_input && p.input) || (!m_is_input && p.output)) {
- item_append(p.name, "", 0, (void *)(m_port_names.size()));
- m_port_names.push_back(p.name);
+ m_port_names.clear();
+ auto const ports = machine().osd().list_midi_ports();
+ m_port_names.reserve(ports.size());
+ for (auto &p : ports)
+ {
+ if ((m_is_input && p.input) || (!m_is_input && p.output))
+ {
+ item_append(p.name, 0, (void *)(m_port_names.size()));
+ m_port_names.emplace_back(p.name);
}
-}
-
-
-//-------------------------------------------------
-// recompute_metrics - recompute metrics
-//-------------------------------------------------
-
-void menu_midi_inout::recompute_metrics(uint32_t width, uint32_t height, float aspect)
-{
- menu::recompute_metrics(width, height, aspect);
-}
-
-
-//-------------------------------------------------
-// menu_midi_inout_custom_render - perform our special
-// rendering
-//-------------------------------------------------
-
-void menu_midi_inout::custom_render(uint32_t flags, void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2)
-{
-}
-
-
-//-------------------------------------------------
-// menu_activated - handle menu gaining focus
-//-------------------------------------------------
-
-void menu_midi_inout::menu_activated()
-{
- // scripts or the other form of the menu could have changed something in the mean time
- reset(reset_options::REMEMBER_POSITION);
-}
-
+ }
-//-------------------------------------------------
-// menu_deactivated - handle menu losing focus
-//-------------------------------------------------
+ if (m_port_names.empty())
+ {
+ item_append(
+ m_is_input ? _("menu-midiport", "[no MIDI input ports available]") : _("menu-midiport", "[no MIDI output ports available]"),
+ FLAG_DISABLE,
+ nullptr);
+ }
-void menu_midi_inout::menu_deactivated()
-{
+ item_append(menu_item_type::SEPARATOR);
}
} // namespace ui
-
diff --git a/src/frontend/mame/ui/midiinout.h b/src/frontend/mame/ui/midiinout.h
index 60f21d15929..522a1cf652c 100644
--- a/src/frontend/mame/ui/midiinout.h
+++ b/src/frontend/mame/ui/midiinout.h
@@ -15,25 +15,29 @@
#include "ui/menu.h"
+#include <functional>
+#include <string>
+#include <vector>
+
namespace ui {
class menu_midi_inout : public menu
{
public:
- menu_midi_inout(mame_ui_manager &mui, render_target &target, bool is_input, std::string *channel);
- virtual ~menu_midi_inout() override;
+ using handler_function = std::function<void (std::string const &)>;
-protected:
- virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
- virtual void custom_render(uint32_t flags, void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
- virtual void menu_activated() override;
- virtual void menu_deactivated() override;
+ menu_midi_inout(
+ mame_ui_manager &mui,
+ render_target &target,
+ bool is_input,
+ handler_function &&handler);
+ virtual ~menu_midi_inout() override;
private:
- std::vector<std::string> m_port_names;
- std::string *m_channel;
- bool m_is_input;
+ handler_function const m_handler;
+ std::vector<std::string> m_port_names;
+ bool const m_is_input;
virtual void populate() override;
virtual bool handle(event const *ev) override;
diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp
index 44232cf2879..ecc39fe79e0 100644
--- a/src/frontend/mame/ui/swlist.cpp
+++ b/src/frontend/mame/ui/swlist.cpp
@@ -56,18 +56,17 @@ static bool is_valid_softlist_part_char(char32_t ch)
menu_software_parts::menu_software_parts(
mame_ui_manager &mui,
render_target &target,
- const software_info *info,
+ const software_info &info,
const char *interface,
- const software_part **part,
bool other_opt,
- result &result)
+ handler_function &&handler)
: menu(mui, target)
- , m_result(result)
+ , m_handler(std::move(handler))
+ , m_info(info)
+ , m_interface(interface)
+ , m_other_opt(other_opt)
{
- m_info = info;
- m_interface = interface;
- m_selected_part = part;
- m_other_opt = other_opt;
+ set_heading(util::string_format(_("%1$s (%2$s)"), info.longname(), info.shortname()));
}
@@ -107,19 +106,22 @@ void menu_software_parts::populate()
item_append(_("[software list]"), 0, &entry3);
}
- for (const software_part &swpart : m_info->parts())
+ for (const software_part &swpart : m_info.parts())
{
if (swpart.matches_interface(m_interface))
{
software_part_menu_entry &entry(*m_entries.emplace(m_entries.end()));
// 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)"
- std::string menu_part_name(swpart.name());
- if (swpart.feature("part_id") != nullptr)
- menu_part_name.append(" (").append(swpart.feature("part_id")).append(")");
+ // if not, we simply display "part_name"; if yes we display "part_id (part_name)"
+ std::string menu_part_name;
+ auto const partid = swpart.feature("part_id");
+ if (partid)
+ menu_part_name = string_format(_("%1$s (%2$s)"), partid, swpart.name());
+ else
+ menu_part_name = swpart.name();
entry.type = result::ENTRY;
entry.part = &swpart;
- item_append(m_info->shortname(), menu_part_name, 0, &entry);
+ item_append(std::move(menu_part_name), m_info.shortname(), 0, &entry);
}
}
@@ -136,9 +138,7 @@ bool menu_software_parts::handle(event const *ev)
if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref)
{
software_part_menu_entry *entry = (software_part_menu_entry *)ev->itemref;
- m_result = entry->type;
- *m_selected_part = entry->part;
- stack_pop();
+ m_handler(entry->type, entry->part);
}
return false;
@@ -153,15 +153,20 @@ bool menu_software_parts::handle(event const *ev)
// ctor
//-------------------------------------------------
-menu_software_list::menu_software_list(mame_ui_manager &mui, render_target &target, software_list_device *swlist, const char *interface, std::string &result)
- : menu(mui, target), m_result(result)
+menu_software_list::menu_software_list(
+ mame_ui_manager &mui,
+ render_target &target,
+ software_list_device &swlist,
+ const char *interface,
+ handler_function &&handler)
+ : menu(mui, target)
+ , m_handler(std::move(handler))
+ , m_swlist(swlist)
+ , m_interface(interface)
+ , m_ordered_by_shortname(false)
{
- set_heading(swlist->description());
-
+ set_heading(swlist.description());
set_process_flags(PROCESS_IGNOREPAUSE);
- m_swlist = swlist;
- m_interface = interface;
- m_ordered_by_shortname = false;
}
@@ -186,7 +191,7 @@ void menu_software_list::append_software_entry(const software_info &swinfo)
// check if at least one of the parts has the correct interface and add a menu entry only in this case
for (const software_part &swpart : swinfo.parts())
{
- if (swpart.matches_interface(m_interface) && m_swlist->is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE)
+ if (swpart.matches_interface(m_interface) && m_swlist.is_compatible(swpart) == SOFTWARE_IS_COMPATIBLE)
{
entry_updated = true;
entry.short_name.assign(swinfo.shortname());
@@ -257,7 +262,7 @@ void menu_software_list::populate()
{
// build up the list of entries for the menu
if (m_entrylist.empty())
- for (const software_info &swinfo : m_swlist->get_info())
+ for (const software_info &swinfo : m_swlist.get_info())
append_software_entry(swinfo);
if (m_entrylist.size() > 1)
@@ -332,9 +337,9 @@ bool menu_software_list::handle(event const *ev)
else if (ev->itemref)
{
// handle selections
+ m_search.clear();
entry_info *info = (entry_info *)ev->itemref;
- m_result = info->short_name;
- stack_pop();
+ m_handler(info->short_name);
}
return false;
}
@@ -392,13 +397,16 @@ bool menu_software_list::handle(event const *ev)
// ctor
//-------------------------------------------------
-menu_software::menu_software(mame_ui_manager &mui, render_target &target, const char *interface, software_list_device **result)
+menu_software::menu_software(
+ mame_ui_manager &mui,
+ render_target &target,
+ const char *interface,
+ handler_function &&handler)
: menu(mui, target)
+ , m_interface(interface)
+ , m_handler(std::move(handler))
{
- set_heading(_("Software List"));
-
- m_interface = interface;
- m_result = result;
+ set_heading(_("Software Lists"));
}
@@ -422,24 +430,34 @@ void menu_software::populate()
// Add original software lists for this system
software_list_device_enumerator iter(machine().config().root_device());
for (software_list_device &swlistdev : iter)
+ {
if (swlistdev.is_original())
+ {
if (!swlistdev.get_info().empty() && m_interface != nullptr)
{
bool found = false;
for (const software_info &swinfo : swlistdev.get_info())
+ {
for (const software_part &swpart : swinfo.parts())
+ {
if (swpart.matches_interface(m_interface))
{
found = true;
break;
}
+ }
+ }
if (found)
item_append(swlistdev.description(), 0, (void *)&swlistdev);
}
+ }
+ }
// add compatible software lists for this system
for (software_list_device &swlistdev : iter)
+ {
if (swlistdev.is_compatible())
+ {
if (!swlistdev.get_info().empty() && m_interface != nullptr)
{
bool found = false;
@@ -458,6 +476,8 @@ void menu_software::populate()
}
have_compatible = true;
}
+ }
+ }
item_append(menu_item_type::SEPARATOR);
}
@@ -472,8 +492,8 @@ bool menu_software::handle(event const *ev)
if (ev && (ev->iptkey == IPT_UI_SELECT))
{
//menu::stack_push<menu_software_list>(ui(), target(), (software_list_config *)ev->itemref, image);
- *m_result = reinterpret_cast<software_list_device *>(ev->itemref);
- stack_pop();
+ auto *const result = reinterpret_cast<software_list_device *>(ev->itemref);
+ m_handler(result);
}
return false;
diff --git a/src/frontend/mame/ui/swlist.h b/src/frontend/mame/ui/swlist.h
index b7616dc5e56..011f7674a51 100644
--- a/src/frontend/mame/ui/swlist.h
+++ b/src/frontend/mame/ui/swlist.h
@@ -13,7 +13,10 @@
#include "ui/menu.h"
+#include <functional>
#include <list>
+#include <string>
+#include <string_view>
namespace ui {
@@ -25,14 +28,21 @@ class menu_software_parts : public menu
public:
enum class result
{
- INVALID = -1,
- EMPTY = 0x2000,
+ EMPTY,
FMGR,
SWLIST,
ENTRY
};
- menu_software_parts(mame_ui_manager &mui, render_target &target, const software_info *info, const char *interface, const software_part **part, bool other_opt, result &result);
+ using handler_function = std::function<void (result, software_part const *)>;
+
+ menu_software_parts(
+ mame_ui_manager &mui,
+ render_target &target,
+ software_info const &info,
+ char const *interface,
+ bool other_opt,
+ handler_function &&handler);
virtual ~menu_software_parts() override;
private:
@@ -47,12 +57,11 @@ private:
virtual bool handle(event const *ev) override;
// variables
+ handler_function const m_handler;
entry_list m_entries;
- const software_info * m_info;
- const char * m_interface;
- const software_part ** m_selected_part;
+ software_info const & m_info;
+ char const *const m_interface;
bool m_other_opt;
- result & m_result;
};
@@ -61,7 +70,14 @@ private:
class menu_software_list : public menu
{
public:
- menu_software_list(mame_ui_manager &mui, render_target &target, software_list_device *swlist, const char *interface, std::string &result);
+ using handler_function = std::function<void (std::string_view)>;
+
+ menu_software_list(
+ mame_ui_manager &mui,
+ render_target &target,
+ software_list_device &swlist,
+ char const *interface,
+ handler_function &&handler);
virtual ~menu_software_list() override;
protected:
@@ -81,18 +97,18 @@ private:
};
// variables
- software_list_device * m_swlist; // currently selected list
- const char * m_interface;
- std::string & m_result;
- std::list<entry_info> m_entrylist;
- std::string m_search;
- bool m_ordered_by_shortname;
+ handler_function const m_handler;
+ software_list_device & m_swlist; // currently selected list
+ char const *const m_interface;
+ std::list<entry_info> m_entrylist;
+ std::string m_search;
+ bool m_ordered_by_shortname;
virtual void populate() override;
virtual bool handle(event const *ev) override;
// functions
- void append_software_entry(const software_info &swinfo);
+ void append_software_entry(software_info const &swinfo);
void update_search(void *selectedref);
};
@@ -102,14 +118,20 @@ private:
class menu_software : public menu
{
public:
- menu_software(mame_ui_manager &mui, render_target &target, const char *interface, software_list_device **result);
+ using handler_function = std::function<void (software_list_device *)>;
+
+ menu_software(
+ mame_ui_manager &mui,
+ render_target &target,
+ char const *interface,
+ handler_function &&handler);
virtual ~menu_software() override;
virtual void populate() override;
virtual bool handle(event const *ev) override;
private:
- const char * m_interface;
- software_list_device ** m_result;
+ char const *const m_interface;
+ handler_function const m_handler;
};
} // namespace ui
diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp
index e0696986d13..f29f02876ad 100644
--- a/src/lib/formats/flopimg.cpp
+++ b/src/lib/formats/flopimg.cpp
@@ -183,21 +183,20 @@ bool floppy_image_format_t::supports_save() const noexcept
return false;
}
-bool floppy_image_format_t::extension_matches(const char *file_name) const
+bool floppy_image_format_t::extension_matches(std::string_view file_name) const noexcept
{
- const char *ext = strrchr(file_name, '.');
- if(!ext)
+ auto const sep = file_name.rfind('.');
+ if(std::string_view::npos == sep)
return false;
- ext++;
- int elen = strlen(ext);
- const char *rext = extensions();
+ auto const ext = file_name.substr(sep + 1);
+ char const *rext = extensions();
for(;;) {
- const char *next_ext = strchr(rext, ',');
- int rlen = next_ext ? next_ext - rext : strlen(rext);
- if(rlen == elen && !memcmp(ext, rext, rlen))
+ char const *next_ext = strchr(rext, ',');
+ int const rlen = next_ext ? (next_ext - rext) : strlen(rext);
+ if(std::string_view(rext, rlen) == ext)
return true;
if(next_ext)
- rext = next_ext +1;
+ rext = next_ext + 1;
else
break;
}
diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h
index 3c0acd4fedb..af90d8528b2 100644
--- a/src/lib/formats/flopimg.h
+++ b/src/lib/formats/flopimg.h
@@ -93,7 +93,7 @@ public:
//! This checks if the file has the proper extension for this format.
//! @param file_name
//! @returns true if file matches the extension.
- bool extension_matches(const char *file_name) const;
+ bool extension_matches(std::string_view file_name) const noexcept;
protected:
//! Input for convert_to_edge
diff --git a/src/lib/util/zippath.cpp b/src/lib/util/zippath.cpp
index ef4e4334db5..c498dcbbf52 100644
--- a/src/lib/util/zippath.cpp
+++ b/src/lib/util/zippath.cpp
@@ -713,30 +713,29 @@ std::error_condition zippath_fopen(std::string_view filename, uint32_t openflags
filerr = std::errc::permission_denied;
else
filerr = std::errc::no_such_file_or_directory;
- goto done;
}
else if (osd::directory::entry::entry_type::DIR == entry_type)
{
filerr = std::errc::is_a_directory;
- goto done;
}
else if (openflags & OPEN_FLAG_WRITE)
{
filerr = std::errc::permission_denied;
- goto done;
}
-
- // attempt to read the file
- filerr = create_core_file_from_zip(*zip, file);
- if (filerr)
- goto done;
-
- // update subpath, if appropriate
- if (subpath.empty())
- subpath.assign(zip->current_name());
+ else
+ {
+ // attempt to read the file
+ filerr = create_core_file_from_zip(*zip, file);
+ if (!filerr)
+ {
+ // update subpath, if appropriate
+ if (subpath.empty())
+ subpath.assign(zip->current_name());
+ }
+ }
// we're done
- goto done;
+ break;
}
}
@@ -748,6 +747,9 @@ std::error_condition zippath_fopen(std::string_view filename, uint32_t openflags
// if we errored, then go up a directory
if (filerr)
{
+ if (std::errc::no_such_file_or_directory != filerr)
+ break;
+
// go up a directory
auto temp = zippath_parent(mainpath);
@@ -773,7 +775,6 @@ std::error_condition zippath_fopen(std::string_view filename, uint32_t openflags
}
}
-done:
// store the revised path
revised_path.clear();
if (!filerr)
diff --git a/src/mame/casio/pickytlk.cpp b/src/mame/casio/pickytlk.cpp
index e3ba1612eca..8bf0c078195 100644
--- a/src/mame/casio/pickytlk.cpp
+++ b/src/mame/casio/pickytlk.cpp
@@ -69,7 +69,7 @@ namespace {
class pickytlk_base_state : public driver_device
{
public:
- DECLARE_CROSSHAIR_MAPPER_MEMBER(pen_y_mapper);
+ float pen_y_mapper(float linear_value);
ioport_value pen_y_rescale_r();
ioport_value pen_target_r();
@@ -171,11 +171,11 @@ void pickytlk_base_state::machine_reset()
m_pen_target = PEN_TARGET_LCD;
}
-CROSSHAIR_MAPPER_MEMBER(pickytlk_base_state::pen_y_mapper)
+float pickytlk_base_state::pen_y_mapper(float linear_value)
{
// Parameter `linear_value` is ignored, since we will read the input port directly
// for adjustments, just need to return that value in the expected range [0.0f..1.0f].
- return (float) pen_y_rescale_r() / 0xff;
+ return float(pen_y_rescale_r()) / 0xff;
}
ioport_value pickytlk_base_state::pen_y_rescale_r()
diff --git a/src/mame/sega/sega_beena.cpp b/src/mame/sega/sega_beena.cpp
index f434f4f53c1..2446fb1519a 100644
--- a/src/mame/sega/sega_beena.cpp
+++ b/src/mame/sega/sega_beena.cpp
@@ -1789,7 +1789,7 @@ public:
void sega_beena(machine_config &config);
- virtual DECLARE_CROSSHAIR_MAPPER_MEMBER(pen_y_mapper);
+ virtual float pen_y_mapper(float linear_value);
protected:
virtual void video_start() override ATTR_COLD;
@@ -2019,7 +2019,7 @@ void sega_beena_state::update_sensors(offs_t offset)
}
}
-CROSSHAIR_MAPPER_MEMBER(sega_beena_state::pen_y_mapper)
+float sega_beena_state::pen_y_mapper(float linear_value)
{
// TODO: Either remove or adapt for Storyware layout
return linear_value;
diff --git a/src/mame/sega/sega_ferie.cpp b/src/mame/sega/sega_ferie.cpp
index 097168c1f55..b7a988e98b4 100644
--- a/src/mame/sega/sega_ferie.cpp
+++ b/src/mame/sega/sega_ferie.cpp
@@ -88,7 +88,7 @@ public:
void sega_ferie(machine_config &config);
- DECLARE_CROSSHAIR_MAPPER_MEMBER(pen_y_mapper);
+ float pen_y_mapper(float linear_value);
ioport_value pen_y_rescale_r();
ioport_value pen_target_r();
@@ -321,11 +321,11 @@ void sega_ferie_state::machine_reset()
m_pen_target = PEN_TARGET_LCD;
}
-CROSSHAIR_MAPPER_MEMBER(sega_ferie_state::pen_y_mapper)
+float sega_ferie_state::pen_y_mapper(float linear_value)
{
// Parameter `linear_value` is ignored, since we will read the input port directly
// for adjustments, just need to return that value in the expected range [0.0f..1.0f].
- return (float) pen_y_rescale_r() / 0xff;
+ return float(pen_y_rescale_r()) / 0xff;
}
ioport_value sega_ferie_state::pen_y_rescale_r()