summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/ui/ui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/ui/ui.cpp')
-rw-r--r--src/frontend/mame/ui/ui.cpp904
1 files changed, 673 insertions, 231 deletions
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index 663354420d2..e697f861da2 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -33,33 +33,26 @@
#include "emuopts.h"
#include "mameopts.h"
#include "drivenum.h"
+#include "fileio.h"
#include "natkeyboard.h"
#include "render.h"
#include "cheat.h"
#include "rendfont.h"
+#include "rendlay.h"
#include "romload.h"
+#include "screen.h"
+#include "speaker.h"
#include "uiinput.h"
+// FIXME: allow OSD module headers to be included in a less ugly way
+#include "../osd/modules/lib/osdlib.h"
#include "../osd/modules/lib/osdobj_common.h"
-#include <chrono>
#include <functional>
#include <type_traits>
/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-enum
-{
- LOADSAVE_NONE,
- LOADSAVE_LOAD,
- LOADSAVE_SAVE
-};
-
-
-/***************************************************************************
LOCAL VARIABLES
***************************************************************************/
@@ -160,6 +153,63 @@ static uint32_t const mouse_bitmap[32*32] =
};
+enum class mame_ui_manager::ui_callback_type : int
+{
+ NOINPUT,
+ GENERAL,
+ MODAL,
+ MENU,
+ CUSTOM
+};
+
+
+struct mame_ui_manager::active_pointer
+{
+ active_pointer(ui_event const &event)
+ : target(event.target)
+ , updated(std::chrono::steady_clock::time_point::min())
+ , type(event.pointer_type)
+ , ptrid(event.pointer_id)
+ , x(-1.0F)
+ , y(-1.0F)
+ {
+ }
+
+ bool operator<(std::pair<render_target *, u16> const &val) const noexcept
+ {
+ return std::make_pair(target, ptrid) < val;
+ }
+
+ render_target *target;
+ std::chrono::steady_clock::time_point updated;
+ osd::ui_event_handler::pointer type;
+ u16 ptrid;
+ float x, y;
+};
+
+
+struct mame_ui_manager::pointer_options
+{
+ pointer_options()
+ : timeout(std::chrono::seconds(3))
+ , hide_inactive(true)
+ , timeout_set(false)
+ , hide_inactive_set(false)
+ {
+ }
+
+ bool options_set() const
+ {
+ return timeout_set || hide_inactive_set;
+ }
+
+ std::chrono::steady_clock::duration timeout;
+ bool hide_inactive;
+ bool timeout_set;
+ bool hide_inactive_set;
+};
+
+
//-------------------------------------------------
// ctor - set up the user interface
//-------------------------------------------------
@@ -168,8 +218,8 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
: ui_manager(machine)
, m_font()
, m_handler_callback()
- , m_handler_callback_type(ui_callback_type::GENERAL)
- , m_handler_param(0)
+ , m_handler_callback_type(ui_callback_type::NOINPUT)
+ , m_ui_active(true)
, m_single_step(false)
, m_showfps(false)
, m_showfps_end(0)
@@ -177,16 +227,18 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
, m_popup_text_end(0)
, m_mouse_bitmap(32, 32)
, m_mouse_arrow_texture(nullptr)
- , m_mouse_show(false)
+ , m_pointers_changed(false)
, m_target_font_height(0)
, m_has_warnings(false)
, m_unthrottle_mute(false)
+ , m_image_display_enabled(true)
, m_machine_info()
, m_unemulated_features()
, m_imperfect_features()
, m_last_launch_time(std::time_t(-1))
, m_last_warning_time(std::time_t(-1))
-{ }
+{
+}
mame_ui_manager::~mame_ui_manager()
{
@@ -200,8 +252,6 @@ void mame_ui_manager::init()
ui::system_list::instance().cache_data(options());
// initialize the other UI bits
- ui_gfx_init(machine());
-
m_ui_colors.refresh(options());
// update font row info from setting
@@ -209,7 +259,7 @@ void mame_ui_manager::init()
// more initialization
set_handler(
- ui_callback_type::GENERAL,
+ ui_callback_type::NOINPUT,
handler_callback_func(
[this] (render_container &container) -> uint32_t
{
@@ -217,14 +267,18 @@ void mame_ui_manager::init()
return 0;
}));
m_non_char_keys_down = std::make_unique<uint8_t[]>((std::size(non_char_keys) + 7) / 8);
- m_mouse_show = machine().system().flags & machine_flags::CLICKABLE_ARTWORK ? true : false;
// request notification callbacks
+ machine().add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(&mame_ui_manager::frame_update, this));
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&mame_ui_manager::exit, this));
machine().configuration().config_register(
"ui_warnings",
- configuration_manager::load_delegate(&mame_ui_manager::config_load, this),
- configuration_manager::save_delegate(&mame_ui_manager::config_save, this));
+ configuration_manager::load_delegate(&mame_ui_manager::config_load_warnings, this),
+ configuration_manager::save_delegate(&mame_ui_manager::config_save_warnings, this));
+ machine().configuration().config_register(
+ "pointer_input",
+ configuration_manager::load_delegate(&mame_ui_manager::config_load_pointers, this),
+ configuration_manager::save_delegate(&mame_ui_manager::config_save_pointers, this));
// create mouse bitmap
uint32_t *dst = &m_mouse_bitmap.pix(0);
@@ -245,6 +299,25 @@ void mame_ui_manager::update_target_font_height()
//-------------------------------------------------
+// exit - called for each emulated frame
+//-------------------------------------------------
+
+void mame_ui_manager::frame_update()
+{
+ // this hackery is needed to ensure natural keyboard and clickable artwork input is in sync with I/O ports
+ if (ui_callback_type::GENERAL == m_handler_callback_type)
+ {
+ process_ui_events();
+ for (auto *target = machine().render().first_target(); target; target = target->next())
+ {
+ if (!target->hidden())
+ target->update_pointer_fields();
+ }
+ }
+}
+
+
+//-------------------------------------------------
// exit - clean up ourselves on exit
//-------------------------------------------------
@@ -263,10 +336,14 @@ void mame_ui_manager::exit()
//-------------------------------------------------
-// config_load - load configuration data
+// config_load_warnings - load info on last time
+// emulation status warnings showed
//-------------------------------------------------
-void mame_ui_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
+void mame_ui_manager::config_load_warnings(
+ config_type cfg_type,
+ config_level cfg_level,
+ util::xml::data_node const *parentnode)
{
// make sure it's relevant and there's data available
if (config_type::SYSTEM == cfg_type)
@@ -304,10 +381,13 @@ void mame_ui_manager::config_load(config_type cfg_type, config_level cfg_level,
//-------------------------------------------------
-// config_save - save configuration data
+// config_save_warnings - save information on
+// last time emulation status warnings showed
//-------------------------------------------------
-void mame_ui_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
+void mame_ui_manager::config_save_warnings(
+ config_type cfg_type,
+ util::xml::data_node *parentnode)
{
// only save system-level configuration when times are valid
if ((config_type::SYSTEM == cfg_type) && (std::time_t(-1) != m_last_launch_time) && (std::time_t(-1) != m_last_warning_time))
@@ -335,12 +415,108 @@ void mame_ui_manager::config_save(config_type cfg_type, util::xml::data_node *pa
//-------------------------------------------------
+// config_load_pointers - load pointer input
+// settings
+//-------------------------------------------------
+
+void mame_ui_manager::config_load_pointers(
+ config_type cfg_type,
+ config_level cfg_level,
+ util::xml::data_node const *parentnode)
+{
+ switch (cfg_type)
+ {
+ case config_type::INIT:
+ {
+ int last(-1);
+ for (auto const &target : machine().render().targets())
+ {
+ assert(target.index() >= 0);
+ if (!target.hidden())
+ last = (std::max)(target.index(), last);
+ }
+ m_pointer_options.resize(last + 1);
+ }
+ break;
+
+ case config_type::CONTROLLER:
+ case config_type::SYSTEM:
+ if (!parentnode)
+ break;
+ for (auto const *targetnode = parentnode->get_child("target"); targetnode; targetnode = targetnode->get_next_sibling("target"))
+ {
+ auto const index(targetnode->get_attribute_int("index", -1));
+ if ((0 <= index) && (m_pointer_options.size() > index))
+ {
+ auto const timeout(targetnode->get_attribute_float("activity_timeout", -1.0F));
+ auto const ms(std::lround(timeout * 1000.0F));
+ if ((100 <= ms) && (10'000 >= ms))
+ {
+ m_pointer_options[index].timeout = std::chrono::milliseconds(ms);
+ if (config_type::SYSTEM == cfg_type)
+ m_pointer_options[index].timeout_set = true;
+ }
+
+ auto const hide(targetnode->get_attribute_int("hide_inactive", -1));
+ if (0 <= hide)
+ {
+ m_pointer_options[index].hide_inactive = hide != 0;
+ if (config_type::SYSTEM == cfg_type)
+ m_pointer_options[index].hide_inactive_set = true;
+ }
+ }
+ }
+ break;
+
+ case config_type::DEFAULT:
+ case config_type::FINAL:
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// config_save_pointers - save pointer input
+// settings
+//-------------------------------------------------
+
+void mame_ui_manager::config_save_pointers(
+ config_type cfg_type,
+ util::xml::data_node *parentnode)
+{
+ if (config_type::SYSTEM == cfg_type)
+ {
+ for (std::size_t i = 0; m_pointer_options.size() > i; ++i)
+ {
+ pointer_options const &options(m_pointer_options[i]);
+ if (options.options_set())
+ {
+ util::xml::data_node *const targetnode = parentnode->add_child("target", nullptr);
+ if (targetnode)
+ {
+ targetnode->set_attribute_int("index", i);
+ if (options.timeout_set)
+ {
+ auto const ms(std::chrono::duration_cast<std::chrono::milliseconds>(options.timeout));
+ targetnode->set_attribute_float("activity_timeout", float(ms.count()) * 0.001F);
+ }
+ if (options.hide_inactive_set)
+ targetnode->set_attribute_int("hide_inactive", options.hide_inactive);
+ }
+ }
+ }
+ }
+}
+
+
+//-------------------------------------------------
// initialize - initialize ui lists
//-------------------------------------------------
void mame_ui_manager::initialize(running_machine &machine)
{
m_machine_info = std::make_unique<ui::machine_info>(machine);
+ set_ui_active(!machine_info().has_keyboard() || machine.options().ui_active());
// initialize the on-screen display system
slider_list = slider_init(machine);
@@ -351,7 +527,7 @@ void mame_ui_manager::initialize(running_machine &machine)
const char *const service_mode_dipname = ioport_configurer::string_from_token(DEF_STR(Service_Mode));
for (auto &port : machine.ioport().ports())
for (ioport_field &field : port.second->fields())
- if (field.type() == IPT_DIPSWITCH && strcmp(field.name(), service_mode_dipname) == 0)
+ if ((field.type() == IPT_DIPSWITCH) && (field.name() == service_mode_dipname)) // FIXME: probably breaks with localisation, also issues with multiple devices
field.set_defseq(machine.ioport().type_seq(IPT_SERVICE));
}
@@ -371,6 +547,12 @@ void mame_ui_manager::initialize(running_machine &machine)
void mame_ui_manager::set_handler(ui_callback_type callback_type, handler_callback_func &&callback)
{
+ m_active_pointers.clear();
+ if (!m_display_pointers.empty())
+ {
+ m_display_pointers.clear();
+ m_pointers_changed = true;
+ }
m_handler_callback = std::move(callback);
m_handler_callback_type = callback_type;
}
@@ -434,17 +616,17 @@ void mame_ui_manager::display_startup_screens(bool first_time)
{
// if the user cancels, exit out completely
machine().schedule_exit();
- return UI_HANDLER_CANCEL;
+ return HANDLER_CANCEL;
}
- else if (machine().ui_input().pressed(IPT_UI_CONFIGURE))
+ else if (machine().ui_input().pressed(IPT_UI_MENU))
{
config_menu = true;
- return UI_HANDLER_CANCEL;
+ return HANDLER_CANCEL;
}
else if (poller.poll() != INPUT_CODE_INVALID)
{
// if any key is pressed, just exit
- return UI_HANDLER_CANCEL;
+ return HANDLER_CANCEL;
}
return 0;
@@ -551,7 +733,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
if (!mandatory_images.empty() && show_mandatory_fileman)
{
std::ostringstream warning;
- warning << _("This driver requires images to be loaded in the following device(s): ");
+ warning << _("This system requires media images to be mounted for the following device(s): ");
output_joined_collection(mandatory_images,
[&warning](const std::reference_wrapper<const std::string> &img) { warning << "\"" << img.get() << "\""; },
@@ -627,10 +809,14 @@ void mame_ui_manager::set_startup_text(const char *text, bool force)
// render it; called by video.c
//-------------------------------------------------
-void mame_ui_manager::update_and_render(render_container &container)
+bool mame_ui_manager::update_and_render(render_container &container)
{
// always start clean
- container.empty();
+ for (auto &target : machine().render().targets())
+ {
+ if (target.ui_container())
+ target.ui_container()->empty();
+ }
// if we're paused, dim the whole screen
if (machine().phase() >= machine_phase::RESET && (single_step() || machine().paused()))
@@ -662,8 +848,13 @@ void mame_ui_manager::update_and_render(render_container &container)
if (machine().phase() >= machine_phase::RESET)
mame_machine_manager::instance()->cheat().render_text(*this, container);
+ // draw the FPS counter if it should be visible
+ if (show_fps_counter())
+ draw_fps_counter(container);
+
// call the current UI handler
- m_handler_param = m_handler_callback(container);
+ machine().ui_input().check_ui_inputs();
+ uint32_t const handler_result = m_handler_callback(container);
// display any popup messages
if (osd_ticks() < m_popup_text_end)
@@ -671,29 +862,34 @@ void mame_ui_manager::update_and_render(render_container &container)
else
m_popup_text_end = 0;
- // display the internal mouse cursor
- if (m_mouse_show || (is_menu_active() && machine().options().ui_mouse()))
+ // display the internal pointers
+ bool const pointer_update = m_pointers_changed;
+ m_pointers_changed = false;
+ if (!is_menu_active() || machine().options().ui_mouse())
{
- int32_t mouse_target_x, mouse_target_y;
- bool mouse_button;
- render_target *mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
-
- if (mouse_target != nullptr)
+ const float cursor_size = 0.6 * get_line_height();
+ for (auto const &pointer : m_display_pointers)
{
- float mouse_y=-1,mouse_x=-1;
- if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y))
- {
- const float cursor_size = 0.6 * get_line_height();
- container.add_quad(mouse_x, mouse_y, mouse_x + cursor_size * container.manager().ui_aspect(&container), mouse_y + cursor_size, colors().text_color(), m_mouse_arrow_texture, PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- }
+ render_container &container = *pointer.target.get().ui_container();
+ container.add_quad(
+ pointer.x,
+ pointer.y,
+ pointer.x + cursor_size * container.manager().ui_aspect(&container),
+ pointer.y + cursor_size,
+ rgb_t::white(),
+ m_mouse_arrow_texture,
+ PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
}
- // cancel takes us back to the ingame handler
- if (m_handler_param == UI_HANDLER_CANCEL)
+ // cancel takes us back to the in-game handler
+ if (handler_result & HANDLER_CANCEL)
{
+ machine().ui_input().reset();
set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this));
}
+
+ return pointer_update || (handler_result & HANDLER_UPDATE);
}
@@ -715,19 +911,16 @@ render_font *mame_ui_manager::get_font()
// of a line
//-------------------------------------------------
-float mame_ui_manager::get_line_height()
+float mame_ui_manager::get_line_height(float scale)
{
- int32_t raw_font_pixel_height = get_font()->pixel_height();
- render_target &ui_target = machine().render().ui_target();
- int32_t target_pixel_height = ui_target.height();
- float one_to_one_line_height;
- float scale_factor;
+ int32_t const raw_font_pixel_height = get_font()->pixel_height();
+ float target_pixel_height = machine().render().ui_target().height();
// compute the font pixel height at the nominal size
- one_to_one_line_height = (float)raw_font_pixel_height / (float)target_pixel_height;
+ float const one_to_one_line_height = float(raw_font_pixel_height) / target_pixel_height;
// determine the scale factor
- scale_factor = target_font_height() / one_to_one_line_height;
+ float scale_factor = target_font_height() * scale / one_to_one_line_height;
// if our font is small-ish, do integral scaling
if (raw_font_pixel_height < 24)
@@ -738,17 +931,17 @@ float mame_ui_manager::get_line_height()
if (one_to_one_line_height < UI_MAX_FONT_HEIGHT || raw_font_pixel_height < 12)
scale_factor = 1.0f;
}
-
- // otherwise, just ensure an integral scale factor
else
- scale_factor = floor(scale_factor);
+ {
+ // otherwise, just ensure an integral scale factor
+ scale_factor = floorf(scale_factor);
+ }
}
-
- // otherwise, just make sure we hit an even number of pixels
else
{
- int32_t height = scale_factor * one_to_one_line_height * (float)target_pixel_height;
- scale_factor = (float)height / (one_to_one_line_height * (float)target_pixel_height);
+ // otherwise, just make sure we hit an even number of pixels
+ int32_t height = scale_factor * one_to_one_line_height * target_pixel_height;
+ scale_factor = float(height) / (one_to_one_line_height * target_pixel_height);
}
return scale_factor * one_to_one_line_height;
@@ -771,9 +964,14 @@ float mame_ui_manager::get_char_width(char32_t ch)
// character string
//-------------------------------------------------
+float mame_ui_manager::get_string_width(std::string_view s)
+{
+ return get_string_width(s, get_line_height());
+}
+
float mame_ui_manager::get_string_width(std::string_view s, float text_size)
{
- return get_font()->utf8string_width(get_line_height() * text_size, machine().render().ui_aspect(), s);
+ return get_font()->utf8string_width(text_size, machine().render().ui_aspect(), s);
}
@@ -832,18 +1030,37 @@ void mame_ui_manager::draw_text_full(
float x, float y, float origwrapwidth,
ui::text_layout::text_justify justify, ui::text_layout::word_wrapping wrap,
draw_mode draw, rgb_t fgcolor, rgb_t bgcolor,
+ float *totalwidth, float *totalheight)
+{
+ draw_text_full(
+ container,
+ origs,
+ x, y, origwrapwidth,
+ justify, wrap,
+ draw, fgcolor, bgcolor,
+ totalwidth, totalheight,
+ get_line_height());
+}
+
+void mame_ui_manager::draw_text_full(
+ render_container &container,
+ std::string_view origs,
+ float x, float y, float origwrapwidth,
+ ui::text_layout::text_justify justify, ui::text_layout::word_wrapping wrap,
+ draw_mode draw, rgb_t fgcolor, rgb_t bgcolor,
float *totalwidth, float *totalheight,
float text_size)
{
// create the layout
- auto layout = create_layout(container, origwrapwidth, justify, wrap);
+ ui::text_layout layout(
+ *get_font(), machine().render().ui_aspect(&container) * text_size, text_size,
+ origwrapwidth, justify, wrap);
// append text to it
layout.add_text(
origs,
fgcolor,
- (draw == OPAQUE_) ? bgcolor : rgb_t::transparent(),
- text_size);
+ (draw == OPAQUE_) ? bgcolor : rgb_t::transparent());
// and emit it (if we are asked to do so)
if (draw != NONE)
@@ -924,7 +1141,7 @@ void mame_ui_manager::draw_message_window(render_container &container, std::stri
void mame_ui_manager::show_fps_temp(double seconds)
{
if (!m_showfps)
- m_showfps_end = osd_ticks() + seconds * osd_ticks_per_second();
+ m_showfps_end = std::max<osd_ticks_t>(osd_ticks() + seconds * osd_ticks_per_second(), m_showfps_end);
}
@@ -936,10 +1153,7 @@ void mame_ui_manager::set_show_fps(bool show)
{
m_showfps = show;
if (!show)
- {
- m_showfps = 0;
m_showfps_end = 0;
- }
}
@@ -960,7 +1174,7 @@ bool mame_ui_manager::show_fps() const
bool mame_ui_manager::show_fps_counter()
{
- bool result = m_showfps || osd_ticks() < m_showfps_end;
+ bool const result = m_showfps || (osd_ticks() < m_showfps_end);
if (!result)
m_showfps_end = 0;
return result;
@@ -995,17 +1209,13 @@ bool mame_ui_manager::show_profiler() const
void mame_ui_manager::show_menu()
{
- set_handler(ui_callback_type::MENU, ui::menu::get_ui_handler(*this));
-}
-
-
-//-------------------------------------------------
-// show_mouse - change mouse status
-//-------------------------------------------------
+ for (auto *target = machine().render().first_target(); target; target = target->next())
+ {
+ if (!target->hidden())
+ target->forget_pointers();
+ }
-void mame_ui_manager::show_mouse(bool status)
-{
- m_mouse_show = status;
+ set_handler(ui_callback_type::MENU, ui::menu::get_ui_handler(*this));
}
@@ -1014,10 +1224,9 @@ void mame_ui_manager::show_mouse(bool status)
// UI handler is active
//-------------------------------------------------
-bool mame_ui_manager::is_menu_active(void)
+bool mame_ui_manager::is_menu_active()
{
- return m_handler_callback_type == ui_callback_type::MENU
- || m_handler_callback_type == ui_callback_type::VIEWER;
+ return m_handler_callback_type == ui_callback_type::MENU;
}
@@ -1027,48 +1236,113 @@ bool mame_ui_manager::is_menu_active(void)
***************************************************************************/
//-------------------------------------------------
-// process_natural_keyboard - processes any
-// natural keyboard input
+// process_ui_events - processes queued UI input
+// events
//-------------------------------------------------
-void mame_ui_manager::process_natural_keyboard()
+void mame_ui_manager::process_ui_events()
{
+ // process UI events
+ bool const use_natkbd(machine().natkeyboard().in_use() && (machine().phase() == machine_phase::RUNNING));
ui_event event;
-
- // loop while we have interesting events
while (machine().ui_input().pop_event(&event))
{
- // if this was a UI_EVENT_CHAR event, post it
- if (event.event_type == ui_event::type::IME_CHAR)
- machine().natkeyboard().post_char(event.ch);
- }
+ switch (event.event_type)
+ {
+ case ui_event::type::NONE:
+ case ui_event::type::WINDOW_FOCUS:
+ case ui_event::type::WINDOW_DEFOCUS:
+ case ui_event::type::MOUSE_WHEEL:
+ break;
- // process natural keyboard keys that don't get UI_EVENT_CHARs
- for (int i = 0; i < std::size(non_char_keys); i++)
- {
- // identify this keycode
- input_item_id itemid = non_char_keys[i];
- input_code code = machine().input().code_from_itemid(itemid);
+ case ui_event::type::POINTER_UPDATE:
+ if (event.target)
+ {
+ if (osd::ui_event_handler::pointer::TOUCH != event.pointer_type)
+ {
+ auto pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
+ if ((m_active_pointers.end() == pos) || (pos->target != event.target) || (pos->ptrid != event.pointer_id))
+ pos = m_active_pointers.emplace(pos, event);
+ else
+ assert(pos->type == event.pointer_type);
+ pos->updated = std::chrono::steady_clock::now();
+ event.target->map_point_container(event.pointer_x, event.pointer_y, *event.target->ui_container(), pos->x, pos->y);
+ }
- // ...and determine if it is pressed
- bool pressed = machine().input().code_pressed(code);
+ event.target->pointer_updated(
+ event.pointer_type, event.pointer_id, event.pointer_device,
+ event.pointer_x, event.pointer_y,
+ event.pointer_buttons, event.pointer_pressed, event.pointer_released,
+ event.pointer_clicks);
+ }
+ break;
- // figure out whey we are in the key_down map
- uint8_t *key_down_ptr = &m_non_char_keys_down[i / 8];
- uint8_t key_down_mask = 1 << (i % 8);
+ case ui_event::type::POINTER_LEAVE:
+ if (event.target)
+ {
+ auto const pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
+ if (m_active_pointers.end() != pos)
+ m_active_pointers.erase(pos);
+
+ event.target->pointer_left(
+ event.pointer_type, event.pointer_id, event.pointer_device,
+ event.pointer_x, event.pointer_y,
+ event.pointer_released,
+ event.pointer_clicks);
+ }
+ break;
- if (pressed && !(*key_down_ptr & key_down_mask))
- {
- // this key is now down
- *key_down_ptr |= key_down_mask;
+ case ui_event::type::POINTER_ABORT:
+ if (event.target)
+ {
+ auto const pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
+ if (m_active_pointers.end() != pos)
+ m_active_pointers.erase(pos);
+
+ event.target->pointer_aborted(
+ event.pointer_type, event.pointer_id, event.pointer_device,
+ event.pointer_x, event.pointer_y,
+ event.pointer_released,
+ event.pointer_clicks);
+ }
+ break;
- // post the key
- machine().natkeyboard().post_char(UCHAR_MAMEKEY_BEGIN + code.item_id());
+ case ui_event::type::IME_CHAR:
+ if (use_natkbd)
+ machine().natkeyboard().post_char(event.ch);
+ break;
}
- else if (!pressed && (*key_down_ptr & key_down_mask))
+ }
+
+ // process natural keyboard keys that don't get IME text input events
+ if (use_natkbd)
+ {
+ for (int i = 0; i < std::size(non_char_keys); i++)
{
- // this key is now up
- *key_down_ptr &= ~key_down_mask;
+ // identify this keycode
+ input_item_id itemid = non_char_keys[i];
+ input_code code = machine().input().code_from_itemid(itemid);
+
+ // ...and determine if it is pressed
+ bool pressed = machine().input().code_pressed(code);
+
+ // figure out whey we are in the key_down map
+ uint8_t *key_down_ptr = &m_non_char_keys_down[i / 8];
+ uint8_t key_down_mask = 1 << (i % 8);
+
+ if (pressed && !(*key_down_ptr & key_down_mask))
+ {
+ // this key is now down
+ *key_down_ptr |= key_down_mask;
+
+ // post the key
+ machine().natkeyboard().post_char(UCHAR_MAMEKEY_BEGIN + code.item_id());
+ }
+ else if (!pressed && (*key_down_ptr & key_down_mask))
+ {
+ // this key is now up
+ *key_down_ptr &= ~key_down_mask;
+ }
}
}
}
@@ -1115,6 +1389,7 @@ void mame_ui_manager::decrease_frameskip()
bool mame_ui_manager::can_paste()
{
// check to see if the clipboard is not empty
+ // FIXME: this is expensive - need a cheaper way to check if clipboard contains suitable content
return !osd_get_clipboard_text().empty();
}
@@ -1151,28 +1426,6 @@ void mame_ui_manager::draw_profiler(render_container &container)
//-------------------------------------------------
-// start_save_state
-//-------------------------------------------------
-
-void mame_ui_manager::start_save_state()
-{
- show_menu();
- ui::menu::stack_push<ui::menu_save_state>(*this, machine().render().ui_container(), true);
-}
-
-
-//-------------------------------------------------
-// start_load_state
-//-------------------------------------------------
-
-void mame_ui_manager::start_load_state()
-{
- show_menu();
- ui::menu::stack_push<ui::menu_load_state>(*this, machine().render().ui_container(), true);
-}
-
-
-//-------------------------------------------------
// image_handler_ingame - execute display
// callback function for each image device
//-------------------------------------------------
@@ -1180,7 +1433,7 @@ void mame_ui_manager::start_load_state()
void mame_ui_manager::image_handler_ingame()
{
// run display routine for devices
- if (machine().phase() == machine_phase::RUNNING)
+ if (m_image_display_enabled && machine().phase() == machine_phase::RUNNING)
{
auto layout = create_layout(machine().render().ui_container());
@@ -1212,11 +1465,10 @@ void mame_ui_manager::image_handler_ingame()
uint32_t mame_ui_manager::handler_ingame(render_container &container)
{
- bool is_paused = machine().paused();
+ // let the OSD do its thing first
+ machine().osd().check_osd_inputs();
- // first draw the FPS counter
- if (show_fps_counter())
- draw_fps_counter(container);
+ bool is_paused = machine().paused();
// draw the profiler if visible
if (show_profiler())
@@ -1230,8 +1482,8 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
}
// determine if we should disable the rest of the UI
- bool has_keyboard = machine_info().has_keyboard();
- bool ui_disabled = (has_keyboard && !machine().ui_active());
+ bool const has_keyboard = machine_info().has_keyboard();
+ bool const ui_disabled = !ui_active();
// is ScrLk UI toggling applicable here?
if (has_keyboard)
@@ -1240,20 +1492,42 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
if (machine().ui_input().pressed(IPT_UI_TOGGLE_UI))
{
// toggle the UI
- machine().set_ui_active(!machine().ui_active());
+ set_ui_active(!ui_active());
// display a popup indicating the new status
std::string const name = get_general_input_setting(IPT_UI_TOGGLE_UI);
- if (machine().ui_active())
+ if (ui_active())
popup_time(2, _("UI controls enabled\nUse %1$s to toggle"), name);
else
popup_time(2, _("UI controls disabled\nUse %1$s to toggle"), name);
}
}
- // is the natural keyboard enabled?
- if (machine().natkeyboard().in_use() && (machine().phase() == machine_phase::RUNNING))
- process_natural_keyboard();
+ // process UI events and update pointers if necessary
+ process_ui_events();
+ display_pointer_vector pointers;
+ pointers.reserve(m_active_pointers.size());
+ auto const now(std::chrono::steady_clock::now());
+ auto expiry(now);
+ render_target *target(nullptr);
+ layout_view const *view(nullptr);
+ bool hide_inactive(true);
+ for (auto const &pointer : m_active_pointers)
+ {
+ if (pointer.target != target)
+ {
+ target = pointer.target;
+ view = &target->current_view();
+ hide_inactive = m_pointer_options[target->index()].hide_inactive && view->hide_inactive_pointers();
+ expiry = now - m_pointer_options[target->index()].timeout;
+ }
+ if (view->show_pointers())
+ {
+ if (!hide_inactive || (osd::ui_event_handler::pointer::PEN == pointer.type) || (pointer.updated >= expiry))
+ pointers.emplace_back(display_pointer{ *target, pointer.type, pointer.x, pointer.y });
+ }
+ }
+ set_pointers(pointers.begin(), pointers.end());
if (!ui_disabled)
{
@@ -1265,7 +1539,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
image_handler_ingame();
if (ui_disabled)
- return ui_disabled;
+ return 0;
if (machine().ui_input().pressed(IPT_UI_CANCEL))
{
@@ -1274,7 +1548,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
}
// turn on menus if requested
- if (machine().ui_input().pressed(IPT_UI_CONFIGURE))
+ if (machine().ui_input().pressed(IPT_UI_MENU))
{
show_menu();
return 0;
@@ -1284,8 +1558,8 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
if (!(machine().debug_flags & DEBUG_FLAG_ENABLED) && machine().ui_input().pressed(IPT_UI_ON_SCREEN_DISPLAY))
{
ui::menu::stack_push<ui::menu_sliders>(*this, machine().render().ui_container(), true);
- set_handler(ui_callback_type::MENU, ui::menu::get_ui_handler(*this));
- return 1;
+ show_menu();
+ return 0;
}
// handle a reset request
@@ -1297,17 +1571,23 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
// handle a request to display graphics/palette
if (machine().ui_input().pressed(IPT_UI_SHOW_GFX))
{
+ for (auto *target = machine().render().first_target(); target; target = target->next())
+ {
+ if (!target->hidden())
+ target->forget_pointers();
+ }
+
if (!is_paused)
machine().pause();
using namespace std::placeholders;
set_handler(
- ui_callback_type::VIEWER,
+ ui_callback_type::MENU,
handler_callback_func(
[this, is_paused] (render_container &container) -> uint32_t
{
return ui_gfx_ui_handler(container, *this, is_paused);
}));
- return is_paused ? 1 : 0;
+ return 0;
}
// handle a tape control key
@@ -1331,15 +1611,31 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
// handle a save state request
if (machine().ui_input().pressed(IPT_UI_SAVE_STATE))
{
- start_save_state();
- return LOADSAVE_SAVE;
+ ui::menu::stack_push<ui::menu_save_state>(*this, machine().render().ui_container(), true);
+ show_menu();
+ return 0;
}
// handle a load state request
if (machine().ui_input().pressed(IPT_UI_LOAD_STATE))
{
- start_load_state();
- return LOADSAVE_LOAD;
+ ui::menu::stack_push<ui::menu_load_state>(*this, machine().render().ui_container(), true);
+ show_menu();
+ return 0;
+ }
+
+ // handle a quick save state request
+ if (machine().ui_input().pressed(IPT_UI_SAVE_STATE_QUICK))
+ {
+ machine().schedule_save("quick");
+ return 0;
+ }
+
+ // handle a quick load state request
+ if (machine().ui_input().pressed(IPT_UI_LOAD_STATE_QUICK))
+ {
+ machine().schedule_load("quick");
+ return 0;
}
// handle a save snapshot request
@@ -1364,7 +1660,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
// handle a toggle cheats request
if (machine().ui_input().pressed(IPT_UI_TOGGLE_CHEAT))
- mame_machine_manager::instance()->cheat().set_enable(!mame_machine_manager::instance()->cheat().enabled());
+ mame_machine_manager::instance()->cheat().set_enable(!mame_machine_manager::instance()->cheat().enabled(), true);
// toggle MNG recording
if (machine().ui_input().pressed(IPT_UI_RECORD_MNG))
@@ -1424,12 +1720,76 @@ void mame_ui_manager::request_quit()
}
else
{
- show_menu();
ui::menu::stack_push<ui::menu_confirm_quit>(*this, machine().render().ui_container());
+ show_menu();
+ }
+}
+
+
+//-------------------------------------------------
+// set_pointer_activity_timeout - set per-target
+// pointer activity timeout
+//-------------------------------------------------
+
+void mame_ui_manager::set_pointer_activity_timeout(int target, std::chrono::steady_clock::duration timeout) noexcept
+{
+ assert((0 <= target) && (m_pointer_options.size() > target));
+ if ((0 <= target) && (m_pointer_options.size() > target))
+ {
+ m_pointer_options[target].timeout = timeout;
+ m_pointer_options[target].timeout_set = true;
+ }
+}
+
+
+//-------------------------------------------------
+// set_hide_inactive_pointers - set per-target
+// hide inactive pointers setting
+//-------------------------------------------------
+
+void mame_ui_manager::set_hide_inactive_pointers(int target, bool hide) noexcept
+{
+ assert((0 <= target) && (m_pointer_options.size() > target));
+ if ((0 <= target) && (m_pointer_options.size() > target))
+ {
+ m_pointer_options[target].hide_inactive = hide;
+ m_pointer_options[target].hide_inactive_set = true;
}
}
+//-------------------------------------------------
+// pointer_activity_timeout - get per-target
+// pointer activity timeout
+//-------------------------------------------------
+
+std::chrono::steady_clock::duration mame_ui_manager::pointer_activity_timeout(int target) const noexcept
+{
+ assert((0 <= target) && (m_pointer_options.size() > target));
+ if ((0 <= target) && (m_pointer_options.size() > target))
+ return m_pointer_options[target].timeout;
+ else
+ return pointer_options().timeout;
+}
+
+
+
+//-------------------------------------------------
+// hide_inactive_pointers - get per-target hide
+// inactive pointers setting
+//-------------------------------------------------
+
+bool mame_ui_manager::hide_inactive_pointers(int target) const noexcept
+{
+ assert((0 <= target) && (m_pointer_options.size() > target));
+ if ((0 <= target) && (m_pointer_options.size() > target))
+ return m_pointer_options[target].hide_inactive;
+ else
+ return pointer_options().hide_inactive;
+}
+
+
+
/***************************************************************************
SLIDER CONTROLS
***************************************************************************/
@@ -1438,7 +1798,7 @@ void mame_ui_manager::request_quit()
// ui_get_slider_list - get the list of sliders
//-------------------------------------------------
-std::vector<ui::menu_item>& mame_ui_manager::get_slider_list(void)
+std::vector<ui::menu_item> &mame_ui_manager::get_slider_list()
{
return slider_list;
}
@@ -1462,11 +1822,16 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
mixer_input info;
for (int item = 0; machine.sound().indexed_mixer_input(item, info); item++)
{
- int32_t maxval = 2000;
- int32_t defval = 1000;
-
std::string str = string_format(_("%1$s Volume"), info.stream->input(info.inputnum).name());
- slider_alloc(std::move(str), 0, defval, maxval, 20, std::bind(&mame_ui_manager::slider_mixervol, this, item, _1, _2));
+ slider_alloc(std::move(str), 0, 1000, 4000, 20, std::bind(&mame_ui_manager::slider_mixervol, this, item, _1, _2));
+ }
+
+ // add speaker panning
+ for (speaker_device &speaker : speaker_device_enumerator(machine.root_device()))
+ {
+ int defpan = floorf(speaker.defpan() * 1000.0f + 0.5f);
+ std::string str = string_format(_("%s '%s' Panning"), speaker.name(), speaker.tag());
+ slider_alloc(std::move(str), -1000, defpan, 1000, 20, std::bind(&mame_ui_manager::slider_panning, this, std::ref(speaker), _1, _2));
}
// add analog adjusters
@@ -1476,8 +1841,7 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
{
if (field.type() == IPT_ADJUSTER)
{
- slider_alloc(field.name(), field.minval(), field.defvalue(), field.maxval(), 1,
- std::bind(&mame_ui_manager::slider_adjuster, this, std::ref(field), _1, _2));
+ slider_alloc(field.name(), field.minval(), field.defvalue(), field.maxval(), 1, std::bind(&mame_ui_manager::slider_adjuster, this, std::ref(field), _1, _2));
}
}
}
@@ -1505,10 +1869,10 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
screen_device_enumerator scriter(machine.root_device());
for (screen_device &screen : scriter)
{
- int defxscale = floor(screen.xscale() * 1000.0f + 0.5f);
- int defyscale = floor(screen.yscale() * 1000.0f + 0.5f);
- int defxoffset = floor(screen.xoffset() * 1000.0f + 0.5f);
- int defyoffset = floor(screen.yoffset() * 1000.0f + 0.5f);
+ int defxscale = floorf(screen.xscale() * 1000.0f + 0.5f);
+ int defyscale = floorf(screen.yscale() * 1000.0f + 0.5f);
+ int defxoffset = floorf(screen.xoffset() * 1000.0f + 0.5f);
+ int defyoffset = floorf(screen.yoffset() * 1000.0f + 0.5f);
std::string screen_desc = machine_info().get_screen_desc(screen);
// add refresh rate tweaker
@@ -1543,20 +1907,18 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
{
laserdisc_overlay_config config;
laserdisc.get_overlay_config(config);
- int defxscale = floor(config.m_overscalex * 1000.0f + 0.5f);
- int defyscale = floor(config.m_overscaley * 1000.0f + 0.5f);
- int defxoffset = floor(config.m_overposx * 1000.0f + 0.5f);
- int defyoffset = floor(config.m_overposy * 1000.0f + 0.5f);
+ int defxscale = floorf(config.m_overscalex * 1000.0f + 0.5f);
+ int defyscale = floorf(config.m_overscaley * 1000.0f + 0.5f);
+ int defxoffset = floorf(config.m_overposx * 1000.0f + 0.5f);
+ int defyoffset = floorf(config.m_overposy * 1000.0f + 0.5f);
// add scale and offset controls per-overlay
std::string str = string_format(_("Laserdisc '%1$s' Horiz Stretch"), laserdisc.tag());
- slider_alloc(std::move(str), 500, (defxscale == 0) ? 1000 : defxscale, 1500, 2,
- std::bind(&mame_ui_manager::slider_overxscale, this, std::ref(laserdisc), _1, _2));
+ slider_alloc(std::move(str), 500, (defxscale == 0) ? 1000 : defxscale, 1500, 2, std::bind(&mame_ui_manager::slider_overxscale, this, std::ref(laserdisc), _1, _2));
str = string_format(_("Laserdisc '%1$s' Horiz Position"), laserdisc.tag());
slider_alloc(std::move(str), -500, defxoffset, 500, 2, std::bind(&mame_ui_manager::slider_overxoffset, this, std::ref(laserdisc), _1, _2));
str = string_format(_("Laserdisc '%1$s' Vert Stretch"), laserdisc.tag());
- slider_alloc(std::move(str), 500, (defyscale == 0) ? 1000 : defyscale, 1500, 2,
- std::bind(&mame_ui_manager::slider_overyscale, this, std::ref(laserdisc), _1, _2));
+ slider_alloc(std::move(str), 500, (defyscale == 0) ? 1000 : defyscale, 1500, 2, std::bind(&mame_ui_manager::slider_overyscale, this, std::ref(laserdisc), _1, _2));
str = string_format(_("Laserdisc '%1$s' Vert Position"), laserdisc.tag());
slider_alloc(std::move(str), -500, defyoffset, 500, 2, std::bind(&mame_ui_manager::slider_overyoffset, this, std::ref(laserdisc), _1, _2));
}
@@ -1613,9 +1975,12 @@ int32_t mame_ui_manager::slider_volume(std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
machine().sound().set_attenuation(newval);
+
+ int32_t curval = machine().sound().attenuation();
if (str)
- *str = string_format(_("%1$3ddB"), machine().sound().attenuation());
- return machine().sound().attenuation();
+ *str = string_format(_(u8"%1$3d\u00a0dB"), curval);
+
+ return curval;
}
@@ -1629,15 +1994,61 @@ int32_t mame_ui_manager::slider_mixervol(int item, std::string *str, int32_t new
mixer_input info;
if (!machine().sound().indexed_mixer_input(item, info))
return 0;
+
if (newval != SLIDER_NOCHANGE)
+ info.stream->input(info.inputnum).set_user_gain(float(newval) * 0.001f);
+
+ int32_t curval = floorf(info.stream->input(info.inputnum).user_gain() * 1000.0f + 0.5f);
+ if (str)
{
- int32_t curval = floor(info.stream->input(info.inputnum).user_gain() * 1000.0f + 0.5f);
- if (newval > curval && (newval - curval) <= 4) newval += 4; // round up on increment
- info.stream->input(info.inputnum).set_user_gain((float)newval * 0.001f);
+ if (curval == 0)
+ *str = _("Mute");
+ else if (curval % 10)
+ *str = string_format(_("%1$.1f%%"), float(curval) * 0.1f);
+ else
+ *str = string_format(_("%1$3d%%"), curval / 10);
}
+
+ return curval;
+}
+
+
+//-------------------------------------------------
+// slider_panning - speaker panning slider
+// callback
+//-------------------------------------------------
+
+int32_t mame_ui_manager::slider_panning(speaker_device &speaker, std::string *str, int32_t newval)
+{
+ if (newval != SLIDER_NOCHANGE)
+ speaker.set_pan(float(newval) * 0.001f);
+
+ int32_t curval = floorf(speaker.pan() * 1000.0f + 0.5f);
if (str)
- *str = string_format("%4.2f", info.stream->input(info.inputnum).user_gain());
- return floorf(info.stream->input(info.inputnum).user_gain() * 1000.0f + 0.5f);
+ {
+ switch (curval)
+ {
+ // preset strings for exact center/left/right
+ case 0:
+ *str = _("Center");
+ break;
+
+ case -1000:
+ *str = _("Left");
+ break;
+
+ case 1000:
+ *str = _("Right");
+ break;
+
+ // otherwise show as floating point
+ default:
+ *str = string_format(_("%1$.3f"), float(curval) * 0.001f);
+ break;
+ }
+ }
+
+ return curval;
}
@@ -1657,7 +2068,7 @@ int32_t mame_ui_manager::slider_adjuster(ioport_field &field, std::string *str,
field.set_user_settings(settings);
}
if (str)
- *str = string_format(_("%1$d%%"), settings.value);
+ *str = string_format(_("%1$3d%%"), settings.value);
return settings.value;
}
@@ -1670,10 +2081,18 @@ int32_t mame_ui_manager::slider_adjuster(ioport_field &field, std::string *str,
int32_t mame_ui_manager::slider_overclock(device_t &device, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
- device.set_clock_scale((float)newval * 0.001f);
+ device.set_clock_scale(double(newval) * 0.001);
+
+ int32_t curval = floor(device.clock_scale() * 1000.0 + 0.5);
if (str)
- *str = string_format(_("%1$3.0f%%"), floor(device.clock_scale() * 100.0 + 0.5));
- return floor(device.clock_scale() * 1000.0 + 0.5);
+ {
+ if (curval % 10)
+ *str = string_format(_("%1$.1f%%"), float(curval) * 0.1f);
+ else
+ *str = string_format(_("%1$3d%%"), curval / 10);
+ }
+
+ return curval;
}
@@ -1691,11 +2110,11 @@ int32_t mame_ui_manager::slider_refresh(screen_device &screen, std::string *str,
int width = screen.width();
int height = screen.height();
const rectangle &visarea = screen.visible_area();
- screen.configure(width, height, visarea, HZ_TO_ATTOSECONDS(defrefresh + (double)newval * 0.001));
+ screen.configure(width, height, visarea, HZ_TO_ATTOSECONDS(defrefresh + double(newval) * 0.001));
}
if (str)
- *str = string_format(_("%1$.3f" UTF8_NBSP "Hz"), screen.frame_period().as_hz());
+ *str = string_format(_(u8"%1$.3f\u00a0Hz"), screen.frame_period().as_hz());
refresh = screen.frame_period().as_hz();
return floor((refresh - defrefresh) * 1000.0 + 0.5);
}
@@ -1711,12 +2130,12 @@ int32_t mame_ui_manager::slider_brightness(screen_device &screen, std::string *s
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_brightness = (float)newval * 0.001f;
+ settings.m_brightness = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_brightness);
- return floor(settings.m_brightness * 1000.0f + 0.5f);
+ return floorf(settings.m_brightness * 1000.0f + 0.5f);
}
@@ -1730,12 +2149,12 @@ int32_t mame_ui_manager::slider_contrast(screen_device &screen, std::string *str
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_contrast = (float)newval * 0.001f;
+ settings.m_contrast = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_contrast);
- return floor(settings.m_contrast * 1000.0f + 0.5f);
+ return floorf(settings.m_contrast * 1000.0f + 0.5f);
}
@@ -1748,12 +2167,12 @@ int32_t mame_ui_manager::slider_gamma(screen_device &screen, std::string *str, i
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_gamma = (float)newval * 0.001f;
+ settings.m_gamma = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_gamma);
- return floor(settings.m_gamma * 1000.0f + 0.5f);
+ return floorf(settings.m_gamma * 1000.0f + 0.5f);
}
@@ -1767,12 +2186,12 @@ int32_t mame_ui_manager::slider_xscale(screen_device &screen, std::string *str,
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_xscale = (float)newval * 0.001f;
+ settings.m_xscale = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_xscale);
- return floor(settings.m_xscale * 1000.0f + 0.5f);
+ return floorf(settings.m_xscale * 1000.0f + 0.5f);
}
@@ -1786,12 +2205,12 @@ int32_t mame_ui_manager::slider_yscale(screen_device &screen, std::string *str,
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_yscale = (float)newval * 0.001f;
+ settings.m_yscale = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_yscale);
- return floor(settings.m_yscale * 1000.0f + 0.5f);
+ return floorf(settings.m_yscale * 1000.0f + 0.5f);
}
@@ -1805,12 +2224,12 @@ int32_t mame_ui_manager::slider_xoffset(screen_device &screen, std::string *str,
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_xoffset = (float)newval * 0.001f;
+ settings.m_xoffset = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_xoffset);
- return floor(settings.m_xoffset * 1000.0f + 0.5f);
+ return floorf(settings.m_xoffset * 1000.0f + 0.5f);
}
@@ -1824,12 +2243,12 @@ int32_t mame_ui_manager::slider_yoffset(screen_device &screen, std::string *str,
render_container::user_settings settings = screen.container().get_user_settings();
if (newval != SLIDER_NOCHANGE)
{
- settings.m_yoffset = (float)newval * 0.001f;
+ settings.m_yoffset = float(newval) * 0.001f;
screen.container().set_user_settings(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_yoffset);
- return floor(settings.m_yoffset * 1000.0f + 0.5f);
+ return floorf(settings.m_yoffset * 1000.0f + 0.5f);
}
@@ -1845,12 +2264,12 @@ int32_t mame_ui_manager::slider_overxscale(laserdisc_device &laserdisc, std::str
laserdisc.get_overlay_config(settings);
if (newval != SLIDER_NOCHANGE)
{
- settings.m_overscalex = (float)newval * 0.001f;
+ settings.m_overscalex = float(newval) * 0.001f;
laserdisc.set_overlay_config(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_overscalex);
- return floor(settings.m_overscalex * 1000.0f + 0.5f);
+ return floorf(settings.m_overscalex * 1000.0f + 0.5f);
}
@@ -1866,12 +2285,12 @@ int32_t mame_ui_manager::slider_overyscale(laserdisc_device &laserdisc, std::str
laserdisc.get_overlay_config(settings);
if (newval != SLIDER_NOCHANGE)
{
- settings.m_overscaley = (float)newval * 0.001f;
+ settings.m_overscaley = float(newval) * 0.001f;
laserdisc.set_overlay_config(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_overscaley);
- return floor(settings.m_overscaley * 1000.0f + 0.5f);
+ return floorf(settings.m_overscaley * 1000.0f + 0.5f);
}
@@ -1887,12 +2306,12 @@ int32_t mame_ui_manager::slider_overxoffset(laserdisc_device &laserdisc, std::st
laserdisc.get_overlay_config(settings);
if (newval != SLIDER_NOCHANGE)
{
- settings.m_overposx = (float)newval * 0.001f;
+ settings.m_overposx = float(newval) * 0.001f;
laserdisc.set_overlay_config(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_overposx);
- return floor(settings.m_overposx * 1000.0f + 0.5f);
+ return floorf(settings.m_overposx * 1000.0f + 0.5f);
}
@@ -1908,12 +2327,12 @@ int32_t mame_ui_manager::slider_overyoffset(laserdisc_device &laserdisc, std::st
laserdisc.get_overlay_config(settings);
if (newval != SLIDER_NOCHANGE)
{
- settings.m_overposy = (float)newval * 0.001f;
+ settings.m_overposy = float(newval) * 0.001f;
laserdisc.set_overlay_config(settings);
}
if (str)
*str = string_format(_("%1$.3f"), settings.m_overposy);
- return floor(settings.m_overposy * 1000.0f + 0.5f);
+ return floorf(settings.m_overposy * 1000.0f + 0.5f);
}
@@ -1925,10 +2344,10 @@ int32_t mame_ui_manager::slider_overyoffset(laserdisc_device &laserdisc, std::st
int32_t mame_ui_manager::slider_flicker([[maybe_unused]] screen_device &screen, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
- vector_options::s_flicker = (float)newval * 0.001f;
+ vector_options::s_flicker = float(newval) * 0.001f;
if (str)
*str = string_format(_("%1$1.2f"), vector_options::s_flicker);
- return floor(vector_options::s_flicker * 1000.0f + 0.5f);
+ return floorf(vector_options::s_flicker * 1000.0f + 0.5f);
}
@@ -1940,10 +2359,10 @@ int32_t mame_ui_manager::slider_flicker([[maybe_unused]] screen_device &screen,
int32_t mame_ui_manager::slider_beam_width_min([[maybe_unused]] screen_device &screen, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
- vector_options::s_beam_width_min = std::min((float)newval * 0.01f, vector_options::s_beam_width_max);
+ vector_options::s_beam_width_min = std::min(float(newval) * 0.01f, vector_options::s_beam_width_max);
if (str != nullptr)
*str = string_format(_("%1$1.2f"), vector_options::s_beam_width_min);
- return floor(vector_options::s_beam_width_min * 100.0f + 0.5f);
+ return floorf(vector_options::s_beam_width_min * 100.0f + 0.5f);
}
@@ -1955,10 +2374,10 @@ int32_t mame_ui_manager::slider_beam_width_min([[maybe_unused]] screen_device &s
int32_t mame_ui_manager::slider_beam_width_max([[maybe_unused]] screen_device &screen, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
- vector_options::s_beam_width_max = std::max((float)newval * 0.01f, vector_options::s_beam_width_min);
+ vector_options::s_beam_width_max = std::max(float(newval) * 0.01f, vector_options::s_beam_width_min);
if (str != nullptr)
*str = string_format(_("%1$1.2f"), vector_options::s_beam_width_max);
- return floor(vector_options::s_beam_width_max * 100.0f + 0.5f);
+ return floorf(vector_options::s_beam_width_max * 100.0f + 0.5f);
}
@@ -1970,10 +2389,10 @@ int32_t mame_ui_manager::slider_beam_width_max([[maybe_unused]] screen_device &s
int32_t mame_ui_manager::slider_beam_dot_size([[maybe_unused]] screen_device &screen, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
- vector_options::s_beam_dot_size = std::max((float)newval * 0.01f, 0.1f);
+ vector_options::s_beam_dot_size = std::max(float(newval) * 0.01f, 0.1f);
if (str != nullptr)
*str = string_format(_("%1$1.2f"), vector_options::s_beam_dot_size);
- return floor(vector_options::s_beam_dot_size * 100.0f + 0.5f);
+ return floorf(vector_options::s_beam_dot_size * 100.0f + 0.5f);
}
@@ -1985,10 +2404,10 @@ int32_t mame_ui_manager::slider_beam_dot_size([[maybe_unused]] screen_device &sc
int32_t mame_ui_manager::slider_beam_intensity_weight([[maybe_unused]] screen_device &screen, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
- vector_options::s_beam_intensity_weight = (float)newval * 0.001f;
+ vector_options::s_beam_intensity_weight = float(newval) * 0.001f;
if (str != nullptr)
*str = string_format(_("%1$1.2f"), vector_options::s_beam_intensity_weight);
- return floor(vector_options::s_beam_intensity_weight * 1000.0f + 0.5f);
+ return floorf(vector_options::s_beam_intensity_weight * 1000.0f + 0.5f);
}
@@ -2004,7 +2423,7 @@ int32_t mame_ui_manager::slider_crossscale(ioport_field &field, std::string *str
field.set_crosshair_scale(float(newval) * 0.001);
if (str)
*str = string_format((field.crosshair_axis() == CROSSHAIR_AXIS_X) ? _("Crosshair Scale X %1$1.3f") : _("Crosshair Scale Y %1$1.3f"), float(newval) * 0.001f);
- return floor(field.crosshair_scale() * 1000.0f + 0.5f);
+ return floorf(field.crosshair_scale() * 1000.0f + 0.5f);
}
#endif
@@ -2033,8 +2452,8 @@ int32_t mame_ui_manager::slider_crossoffset(ioport_field &field, std::string *st
ui::text_layout mame_ui_manager::create_layout(render_container &container, float width, ui::text_layout::text_justify justify, ui::text_layout::word_wrapping wrap)
{
// determine scale factors
- float yscale = get_line_height();
- float xscale = yscale * machine().render().ui_aspect(&container);
+ float const yscale = get_line_height();
+ float const xscale = yscale * machine().render().ui_aspect(&container);
// create the layout
return ui::text_layout(*get_font(), xscale, yscale, width, justify, wrap);
@@ -2170,7 +2589,7 @@ void mame_ui_manager::save_main_option()
return;
}
}
- popup_time(3, "%s", _("\n Configuration saved \n\n"));
+ popup_time(3, "%s", _("\n Settings saved \n\n"));
}
void mame_ui_manager::menu_reset()
@@ -2179,6 +2598,29 @@ void mame_ui_manager::menu_reset()
}
+bool mame_ui_manager::set_ui_event_handler(std::function<bool ()> &&handler)
+{
+ // only allow takeover if there's nothing else happening
+ if (ui_callback_type::GENERAL != m_handler_callback_type)
+ return false;
+
+ for (auto *target = machine().render().first_target(); target; target = target->next())
+ {
+ if (!target->hidden())
+ target->forget_pointers();
+ }
+
+ set_handler(
+ ui_callback_type::CUSTOM,
+ handler_callback_func(
+ [cb = std::move(handler)] (render_container &container) -> uint32_t
+ {
+ return !cb() ? HANDLER_CANCEL : 0;
+ }));
+ return true;
+}
+
+
//-------------------------------------------------
// get_general_input_setting - get the current
// default setting for an input type (useful for