file selector: Add midi connection selection to midi ports

This commit is contained in:
Olivier Galibert 2024-10-29 00:01:41 +01:00
parent 781443d3a5
commit dbc8f01adb
14 changed files with 222 additions and 19 deletions

View File

@ -139,6 +139,8 @@ files {
MAME_DIR .. "src/frontend/mame/ui/mainmenu.h",
MAME_DIR .. "src/frontend/mame/ui/menu.cpp",
MAME_DIR .. "src/frontend/mame/ui/menu.h",
MAME_DIR .. "src/frontend/mame/ui/midiinout.cpp",
MAME_DIR .. "src/frontend/mame/ui/midiinout.h",
MAME_DIR .. "src/frontend/mame/ui/miscmenu.cpp",
MAME_DIR .. "src/frontend/mame/ui/miscmenu.cpp",
MAME_DIR .. "src/frontend/mame/ui/miscmenu.h",

View File

@ -24,6 +24,9 @@
#include "util/corestr.h"
#include "util/zippath.h"
#include "bus/midi/midiinport.h"
#include "bus/midi/midioutport.h"
#include <cstring>
#include <locale>
@ -69,6 +72,7 @@ menu_file_selector::menu_file_selector(
, 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_clicked_directory(std::string::npos, std::string::npos)
{
(void)m_image;
@ -319,6 +323,10 @@ void menu_file_selector::append_entry_menu_item(const file_selector_entry *entry
text = _("[empty slot]");
break;
case SELECTOR_ENTRY_TYPE_MIDI:
text = _("[midi port]");
break;
case SELECTOR_ENTRY_TYPE_CREATE:
text = _("[create]");
break;
@ -360,6 +368,12 @@ void menu_file_selector::select_item(const file_selector_entry &entry)
stack_pop();
break;
case SELECTOR_ENTRY_TYPE_MIDI:
// create
m_result = result::MIDI;
stack_pop();
break;
case SELECTOR_ENTRY_TYPE_CREATE:
// create
m_result = result::CREATE;
@ -491,6 +505,10 @@ void menu_file_selector::populate()
if (m_has_empty)
append_entry(SELECTOR_ENTRY_TYPE_EMPTY, "", "");
// add the "[midi port]" entry if available
if (m_is_midi)
append_entry(SELECTOR_ENTRY_TYPE_MIDI, "", "");
// add the "[create]" entry
if (m_has_create && directory && !directory->is_archive())
append_entry(SELECTOR_ENTRY_TYPE_CREATE, "", "");

View File

@ -37,7 +37,8 @@ public:
EMPTY = 0x1000,
SOFTLIST,
CREATE,
FILE
FILE,
MIDI
};
using handler_function = std::function<void (result result, std::string &&directory, std::string &&file)>;
@ -65,6 +66,7 @@ private:
enum file_selector_entry_type
{
SELECTOR_ENTRY_TYPE_EMPTY,
SELECTOR_ENTRY_TYPE_MIDI,
SELECTOR_ENTRY_TYPE_CREATE,
SELECTOR_ENTRY_TYPE_SOFTWARE_LIST,
SELECTOR_ENTRY_TYPE_DRIVE,
@ -94,6 +96,7 @@ private:
bool const m_has_empty;
bool const m_has_softlist;
bool const m_has_create;
bool const m_is_midi;
std::vector<file_selector_entry> m_entrylist;
std::string m_filename;
std::pair<size_t, size_t> m_clicked_directory;

View File

@ -13,6 +13,7 @@
#include "ui/filecreate.h"
#include "ui/filesel.h"
#include "ui/midiinout.h"
#include "ui/swlist.h"
#include "ui/ui.h"
@ -274,6 +275,10 @@ void menu_control_device_image::menu_activated()
m_state = START_SOFTLIST;
break;
case menu_file_selector::result::MIDI:
m_state = START_MIDI;
break;
default: // return to system
stack_pop();
break;
@ -287,6 +292,22 @@ void menu_control_device_image::menu_activated()
m_state = SELECT_SOFTLIST;
break;
case START_MIDI:
m_midi = "";
menu::stack_push<menu_midi_inout>(ui(), container(), m_image.image_interface(), &m_midi);
m_state = SELECT_MIDI;
break;
case SELECT_MIDI:
if(!m_midi.empty())
{
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();
break;
case START_OTHER_PART:
m_submenu_result.swparts = menu_software_parts::result::INVALID;
menu::stack_push<menu_software_parts>(ui(), container(), m_swi, m_image.image_interface(), &m_swp, true, m_submenu_result.swparts);

View File

@ -30,9 +30,9 @@ public:
protected:
enum
{
START_FILE, START_OTHER_PART, START_SOFTLIST,
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,
CREATE_FILE, CREATE_CONFIRM, CHECK_CREATE, DO_CREATE, SELECT_SOFTLIST, SELECT_MIDI,
LAST_ID
};
@ -63,6 +63,7 @@ private:
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;

View File

@ -0,0 +1,105 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/*********************************************************************
ui/midiinout.cpp
Midi channel selection
*********************************************************************/
#include "emu.h"
#include "ui/midiinout.h"
#include "ui/ui.h"
#include "osdepend.h"
namespace ui {
menu_midi_inout::menu_midi_inout(mame_ui_manager &mui, render_container &container, bool is_input, std::string *channel)
: menu(mui, container)
, m_channel(channel)
, m_is_input(is_input)
{
set_heading(m_is_input ? _("Midi input channel") : _("Midi output channel"));
}
menu_midi_inout::~menu_midi_inout()
{
}
bool menu_midi_inout::handle(event const *ev)
{
if(!ev)
return false;
if(ev->iptkey == IPT_UI_SELECT) {
*m_channel = m_port_names[uintptr_t(ev->itemref)];
stack_pop();
return true;
}
return false;
}
//-------------------------------------------------
// menu_midi_inout_populate - populate the midi_inout
// menu
//-------------------------------------------------
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);
}
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_midi_inout::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// set_custom_space(0.0f, 2.0f * line_height() + 2.0f * tb_border());
}
//-------------------------------------------------
// 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
//-------------------------------------------------
void menu_midi_inout::menu_deactivated()
{
}
} // namespace ui

View File

@ -0,0 +1,44 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/***************************************************************************
ui/midiinout.h
Midi channel selection
***************************************************************************/
#ifndef MAME_FRONTEND_UI_MIDIINOUT_H
#define MAME_FRONTEND_UI_MIDIINOUT_H
#pragma once
#include "ui/menu.h"
namespace ui {
class menu_midi_inout : public menu
{
public:
menu_midi_inout(mame_ui_manager &mui, render_container &container, bool is_input, std::string *channel);
virtual ~menu_midi_inout() override;
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;
private:
std::vector<std::string> m_port_names;
std::string *m_channel;
bool m_is_input;
virtual void populate() override;
virtual bool handle(event const *ev) override;
};
} // namespace ui
#endif // MAME_FRONTEND_UI_MIDIINOUT_H

View File

@ -13,6 +13,7 @@
#pragma once
#include <cstdint>
#include <string>
namespace osd {
@ -35,6 +36,15 @@ public:
virtual void write(uint8_t data) = 0;
};
struct midi_port_info
{
std::string name;
bool input;
bool output;
bool default_input;
bool default_output;
};
} // namespace osd
#endif // MAME_OSD_INTERFACE_MIDIPORT_H

View File

@ -782,3 +782,9 @@ std::unique_ptr<osd::midi_output_port> osd_common_t::create_midi_output(std::str
{
return m_midi->create_output(name);
}
std::vector<osd::midi_port_info> osd_common_t::list_midi_ports()
{
return m_midi->list_midi_ports();
}

View File

@ -242,6 +242,7 @@ public:
virtual std::unique_ptr<osd::midi_input_port> create_midi_input(std::string_view name) override;
virtual std::unique_ptr<osd::midi_output_port> create_midi_output(std::string_view name) override;
virtual std::vector<osd::midi_port_info> list_midi_ports() override;
// FIXME: everything below seems to be osd specific and not part of
// this INTERFACE but part of the osd IMPLEMENTATION

View File

@ -26,23 +26,13 @@
class midi_module
{
public:
struct port_info
{
std::string name;
bool input;
bool output;
bool default_input;
bool default_output;
};
using port_info_vector = std::vector<port_info>;
virtual ~midi_module() = default;
// specific routines
virtual std::unique_ptr<osd::midi_input_port> create_input(std::string_view name) = 0;
virtual std::unique_ptr<osd::midi_output_port> create_output(std::string_view name) = 0;
virtual port_info_vector list_midi_ports() = 0;
virtual std::vector<osd::midi_port_info> list_midi_ports() = 0;
};
#endif // MAME_OSD_MODULES_MIDI_MIDI_MODULE_H

View File

@ -30,7 +30,7 @@ public:
virtual std::unique_ptr<midi_input_port> create_input(std::string_view name) override { return nullptr; }
virtual std::unique_ptr<midi_output_port> create_output(std::string_view name) override { return nullptr; }
virtual port_info_vector list_midi_ports() override { return port_info_vector(); }
virtual std::vector<osd::midi_port_info> list_midi_ports() override { return std::vector<osd::midi_port_info>(); }
};
} // anonymous namespace

View File

@ -41,7 +41,7 @@ public:
virtual std::unique_ptr<midi_input_port> create_input(std::string_view name) override;
virtual std::unique_ptr<midi_output_port> create_output(std::string_view name) override;
virtual port_info_vector list_midi_ports() override;
virtual std::vector<osd::midi_port_info> list_midi_ports() override;
};
@ -177,17 +177,17 @@ std::unique_ptr<midi_output_port> pm_module::create_output(std::string_view name
}
}
midi_module::port_info_vector pm_module::list_midi_ports()
std::vector<osd::midi_port_info> pm_module::list_midi_ports()
{
int const num_devs = Pm_CountDevices();
int const def_input = Pm_GetDefaultInputDeviceID();
int const def_output = Pm_GetDefaultOutputDeviceID();
port_info_vector result;
std::vector<osd::midi_port_info> result;
result.reserve(num_devs);
for (int i = 0; num_devs > i; ++i)
{
auto const pm_info = Pm_GetDeviceInfo(i);
result.emplace_back(port_info{
result.emplace_back(osd::midi_port_info{
pm_info->name,
0 != pm_info->input,
0 != pm_info->output,

View File

@ -16,6 +16,7 @@
#include "emufwd.h"
#include "bitmap.h"
#include "interface/midiport.h"
#include <cstdint>
#include <memory>
@ -97,6 +98,7 @@ public:
// MIDI interface
virtual std::unique_ptr<osd::midi_input_port> create_midi_input(std::string_view name) = 0;
virtual std::unique_ptr<osd::midi_output_port> create_midi_output(std::string_view name) = 0;
virtual std::vector<osd::midi_port_info> list_midi_ports() = 0;
protected:
virtual ~osd_interface() { }