summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/source/luascript/ref-core.rst3
-rw-r--r--docs/source/luascript/ref-render.rst15
-rw-r--r--docs/source/techspecs/layout_files.rst5
-rwxr-xr-xscripts/build/complay.py1
-rw-r--r--src/emu/rendlay.cpp40
-rw-r--r--src/emu/rendlay.h9
-rw-r--r--src/frontend/mame/luaengine.cpp1
-rw-r--r--src/frontend/mame/luaengine_render.cpp3
-rw-r--r--src/frontend/mame/ui/selmenu.cpp1
-rw-r--r--src/frontend/mame/ui/ui.cpp48
-rw-r--r--src/frontend/mame/ui/ui.h2
11 files changed, 101 insertions, 27 deletions
diff --git a/docs/source/luascript/ref-core.rst b/docs/source/luascript/ref-core.rst
index f761b20f5de..7b72d90ebdb 100644
--- a/docs/source/luascript/ref-core.rst
+++ b/docs/source/luascript/ref-core.rst
@@ -587,9 +587,6 @@ driver.is_bios_root (read-only)
driver.requires_artwork (read-only)
A Boolean indicating whether the system requires external artwork to be
usable.
-driver.clickable_artwork (read-only)
- A Boolean indicating whether the system requires clickable artwork features
- to be usable.
driver.unofficial (read-only)
A Boolean indicating whether this is an unofficial but common user
modification to a system.
diff --git a/docs/source/luascript/ref-render.rst b/docs/source/luascript/ref-render.rst
index eee432660dd..7cc1400b3cb 100644
--- a/docs/source/luascript/ref-render.rst
+++ b/docs/source/luascript/ref-render.rst
@@ -754,6 +754,10 @@ manager.machine.video.snapshot_target
Properties
~~~~~~~~~~
+target.ui_container (read-only)
+ The :ref:`render container <luascript-ref-rendercontainer>` for drawing user
+ interface elements over this render target, or ``nil`` for hidden render
+ targets (targets that are not shown to the user directly).
target.index (read-only)
The 1-based index of the render target. This has O(n) complexity.
target.width (read-only)
@@ -810,6 +814,9 @@ Instantiation
manager.machine.render.ui_container
Gets the render container used to draw the user interface, including menus,
sliders and pop-up messages.
+manager.machine.render.targets[index].ui_container
+ Gets the render container used to draw user interface elements over a
+ particular render target.
manager.machine.screens[tag].container
Gets the render container used to draw a given screen.
@@ -1145,10 +1152,16 @@ view.bounds (read-only)
effective bounds of the view in its current configuration. The coordinates
are in view units, which are arbitrary but assumed to have square aspect
ratio.
-view.has_art
+view.has_art (read-only)
A Boolean indicating whether the view has any non-screen items, including
items that are not visible because the user has hidden the item collection
that they belong to.
+view.show_pointers (read/write)
+ A Boolean that sets whether mouse and pon pointers should be displayed for
+ the view.
+view.hide_inactive_pointers (read/write)
+ A Boolean that sets whether mouse pointers for the view should be hidden
+ after a period of inactivity.
.. _luascript-ref-renderlayitem:
diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst
index 297521bf945..a014756a32b 100644
--- a/docs/source/techspecs/layout_files.rst
+++ b/docs/source/techspecs/layout_files.rst
@@ -690,6 +690,11 @@ element. This means a view can reference elements and groups that appear after
it in the file, and parameters from the enclosing scope will have their final
values from the end of the ``mamelayout`` element.
+A ``view`` element may have a ``showpointers`` attribute to set whether mouse
+and pen pointers should be shown for the view. If present, the value must be
+either ``yes`` or ``no``. If the ``showpointers`` attribute is not present, pen
+and mouse pointers are shown for views that contain items bound to I/O ports.
+
The following child elements are allowed inside a ``view`` element:
bounds
diff --git a/scripts/build/complay.py b/scripts/build/complay.py
index f0e330240a1..6519a01de06 100755
--- a/scripts/build/complay.py
+++ b/scripts/build/complay.py
@@ -409,6 +409,7 @@ class LayoutChecker(Minifyer):
self.views[attrs['name']] = self.format_location()
elif not self.VARPATTERN.match(attrs['name']):
self.handle_error('Element view has duplicate name "%s" (previous %s)' % (attrs['name'], self.views[attrs['name']]))
+ self.check_bool_attribute(name, attrs, 'showpointers', None)
self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler))
self.variable_scopes.append({ })
self.item_ids = { }
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index de17b5dae6f..be5413f99ae 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -4000,7 +4000,17 @@ layout_view::layout_view(
, m_elemmap(elemmap)
, m_defvismask(0U)
, m_has_art(false)
+ , m_show_ptr(false)
+ , m_ptr_time_out(true) // FIXME: add attribute for this
+ , m_exp_show_ptr(-1)
{
+ // check for explicit pointer display setting
+ if (viewnode.get_attribute_string_ptr("showpointers"))
+ {
+ m_show_ptr = env.get_attribute_bool(viewnode, "showpointers", false);
+ m_exp_show_ptr = m_show_ptr ? 1 : 0;
+ }
+
// parse the layout
m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0;
view_environment local(env, m_name.c_str());
@@ -4178,6 +4188,7 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
// loop over items and filter by visibility mask
bool first = true;
bool scrfirst = true;
+ bool haveinput = false;
for (item &curitem : m_items)
{
if ((visibility_mask & curitem.visibility_mask()) == curitem.visibility_mask())
@@ -4209,9 +4220,15 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
// accumulate interactive elements
if (!curitem.clickthrough() || curitem.has_input())
m_interactive_items.emplace_back(curitem);
+ if (curitem.has_input())
+ haveinput = true;
}
}
+ // if show pointers isn't explicitly, update it based on visible items
+ if (0 > m_exp_show_ptr)
+ m_show_ptr = haveinput;
+
// if we have an explicit bounds, override it
if (m_expbounds.x1 > m_expbounds.x0)
m_bounds = m_expbounds;
@@ -4283,6 +4300,29 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
//-------------------------------------------------
+// set_show_pointers - set whether pointers
+// should be displayed
+//-------------------------------------------------
+
+void layout_view::set_show_pointers(bool value) noexcept
+{
+ m_show_ptr = value;
+ m_exp_show_ptr = value ? 1 : 0;
+}
+
+
+//-------------------------------------------------
+// set_pointers_time_out - set whether pointers
+// should be hidden after inactivity
+//-------------------------------------------------
+
+void layout_view::set_hide_inactive_pointers(bool value) noexcept
+{
+ m_ptr_time_out = value;
+}
+
+
+//-------------------------------------------------
// set_prepare_items_callback - set handler called
// before adding items to render target
//-------------------------------------------------
diff --git a/src/emu/rendlay.h b/src/emu/rendlay.h
index 7edeb4b40c5..23431e7fd92 100644
--- a/src/emu/rendlay.h
+++ b/src/emu/rendlay.h
@@ -527,6 +527,12 @@ public:
const visibility_toggle_vector &visibility_toggles() const { return m_vistoggles; }
u32 default_visibility_mask() const { return m_defvismask; }
bool has_art() const { return m_has_art; }
+ bool show_pointers() const { return m_show_ptr; }
+ bool hide_inactive_pointers() const { return m_ptr_time_out; }
+
+ // setters
+ void set_show_pointers(bool value) noexcept;
+ void set_hide_inactive_pointers(bool value) noexcept ATTR_COLD;
// set handlers
void set_prepare_items_callback(prepare_items_delegate &&handler) ATTR_COLD;
@@ -621,6 +627,9 @@ private:
render_bounds m_expbounds; // explicit bounds of the view
u32 m_defvismask; // default visibility mask
bool m_has_art; // true if the layout contains non-screen elements
+ bool m_show_ptr; // whether pointers should be displayed
+ bool m_ptr_time_out; // whether pointers should be hidden after inactivity
+ s8 m_exp_show_ptr; // explicitly configured pointer visibility
};
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index c97cc2988bc..6aa2d3840ec 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -1502,7 +1502,6 @@ void lua_engine::initialize()
game_driver_type["no_cocktail"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_COCKTAIL) != 0; });
game_driver_type["is_bios_root"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::IS_BIOS_ROOT) != 0; });
game_driver_type["requires_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::REQUIRES_ARTWORK) != 0; });
- game_driver_type["clickable_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::CLICKABLE_ARTWORK) != 0; });
game_driver_type["unofficial"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::UNOFFICIAL) != 0; });
game_driver_type["no_sound_hw"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_SOUND_HW) != 0; });
game_driver_type["mechanical"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::MECHANICAL) != 0; });
diff --git a/src/frontend/mame/luaengine_render.cpp b/src/frontend/mame/luaengine_render.cpp
index 3fd0bfdba10..8f931f91dac 100644
--- a/src/frontend/mame/luaengine_render.cpp
+++ b/src/frontend/mame/luaengine_render.cpp
@@ -994,6 +994,8 @@ void lua_engine::initialize_render(sol::table &emu)
layout_view_type["effective_aspect"] = sol::property(&layout_view::effective_aspect);
layout_view_type["bounds"] = sol::property(&layout_view::bounds);
layout_view_type["has_art"] = sol::property(&layout_view::has_art);
+ layout_view_type["show_pointers"] = sol::property(&layout_view::show_pointers, &layout_view::set_show_pointers);
+ layout_view_type["hide_inactive_pointers"] = sol::property(&layout_view::hide_inactive_pointers, &layout_view::set_hide_inactive_pointers);
auto layout_view_item_type = sol().registry().new_usertype<layout_view_item>("layout_item", sol::no_constructor);
@@ -1100,6 +1102,7 @@ void lua_engine::initialize_render(sol::table &emu)
auto target_type = sol().registry().new_usertype<render_target>("target", sol::no_constructor);
+ target_type["ui_container"] = sol::property(&render_target::ui_container);
target_type["index"] = sol::property([] (render_target const &t) { return t.index() + 1; });
target_type["width"] = sol::property(&render_target::width);
target_type["height"] = sol::property(&render_target::height);
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index 7791aaff8d1..a5645e79ca8 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -4202,7 +4202,6 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
str << ((flags.machine_flags() & machine_flags::MECHANICAL) ? _("Mechanical System\tYes\n") : _("Mechanical System\tNo\n"));
str << ((flags.machine_flags() & machine_flags::REQUIRES_ARTWORK) ? _("Requires Artwork\tYes\n") : _("Requires Artwork\tNo\n"));
- str << ((flags.machine_flags() & machine_flags::CLICKABLE_ARTWORK) ? _("Requires Clickable Artwork\tYes\n") : _("Requires Clickable Artwork\tNo\n"));
if (flags.machine_flags() & machine_flags::NO_COCKTAIL)
str << _("Support Cocktail\tNo\n");
str << ((flags.machine_flags() & machine_flags::IS_BIOS_ROOT) ? _("System is BIOS\tYes\n") : _("System is BIOS\tNo\n"));
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index a9a4fd5ceed..0c4af7b8ba5 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -38,6 +38,7 @@
#include "render.h"
#include "cheat.h"
#include "rendfont.h"
+#include "rendlay.h"
#include "romload.h"
#include "screen.h"
#include "speaker.h"
@@ -165,7 +166,13 @@ enum class mame_ui_manager::ui_callback_type : int
struct mame_ui_manager::active_pointer
{
- active_pointer(ui_event const &event) : target(event.target), type(event.pointer_type), ptrid(event.pointer_id), x(-1.0F), y(-1.0F)
+ 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)
{
}
@@ -175,6 +182,7 @@ struct mame_ui_manager::active_pointer
}
render_target *target;
+ std::chrono::steady_clock::time_point updated;
osd::ui_event_handler::pointer type;
u16 ptrid;
float x, y;
@@ -198,8 +206,6 @@ 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_update_pointers(false)
, m_pointers_changed(false)
, m_target_font_height(0)
, m_has_warnings(false)
@@ -240,7 +246,6 @@ 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));
@@ -733,7 +738,7 @@ bool mame_ui_manager::update_and_render(render_container &container)
// display the internal pointers
bool const pointer_update = m_pointers_changed;
m_pointers_changed = false;
- if (m_mouse_show || (is_menu_active() && machine().options().ui_mouse()))
+ if (!is_menu_active() || machine().options().ui_mouse())
{
const float cursor_size = 0.6 * get_line_height();
for (auto const &pointer : m_display_pointers)
@@ -1128,12 +1133,12 @@ void mame_ui_manager::process_ui_events()
{
if (osd::ui_event_handler::pointer::TOUCH != event.pointer_type)
{
- m_update_pointers = true;
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);
}
@@ -1150,10 +1155,7 @@ void mame_ui_manager::process_ui_events()
{
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_update_pointers = true;
m_active_pointers.erase(pos);
- }
event.target->pointer_left(
event.pointer_type, event.pointer_id, event.pointer_device,
@@ -1168,10 +1170,7 @@ void mame_ui_manager::process_ui_events()
{
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_update_pointers = true;
m_active_pointers.erase(pos);
- }
event.target->pointer_aborted(
event.pointer_type, event.pointer_id, event.pointer_device,
@@ -1379,15 +1378,20 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
// process UI events and update pointers if necessary
process_ui_events();
- if (m_update_pointers)
+ display_pointer_vector pointers;
+ pointers.reserve(m_active_pointers.size());
+ auto const now(std::chrono::steady_clock::now());
+ for (auto const &pointer : m_active_pointers)
{
- display_pointer_vector pointers;
- pointers.reserve(m_active_pointers.size());
- for (auto const &pointer : m_active_pointers)
- pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
- set_pointers(pointers.begin(), pointers.end());
- m_update_pointers = false;
+ layout_view const &view(pointer.target->current_view());
+ if (view.show_pointers())
+ {
+ // TODO: make timeout configurable
+ if (!view.hide_inactive_pointers() || (osd::ui_event_handler::pointer::PEN == pointer.type) || ((now - pointer.updated) <= std::chrono::seconds(3)))
+ pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
+ }
}
+ set_pointers(pointers.begin(), pointers.end());
if (!ui_disabled)
{
@@ -2400,6 +2404,12 @@ bool mame_ui_manager::set_ui_event_handler(std::function<bool ()> &&handler)
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(
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index 231a6de15cb..d213d861f34 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -298,8 +298,6 @@ private:
display_pointer_vector m_display_pointers;
bitmap_argb32 m_mouse_bitmap;
render_texture * m_mouse_arrow_texture;
- bool m_mouse_show;
- bool m_update_pointers;
bool m_pointers_changed;
ui_options m_ui_options;