Skip to content

Commit 8e7af96

Browse files
committed
emu/rendlay.cpp, ui/ui.cpp: Allow layout views to control pointer display.
1 parent 7662be2 commit 8e7af96

File tree

11 files changed

+101
-27
lines changed

11 files changed

+101
-27
lines changed

docs/source/luascript/ref-core.rst

-3
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,6 @@ driver.is_bios_root (read-only)
587587
driver.requires_artwork (read-only)
588588
A Boolean indicating whether the system requires external artwork to be
589589
usable.
590-
driver.clickable_artwork (read-only)
591-
A Boolean indicating whether the system requires clickable artwork features
592-
to be usable.
593590
driver.unofficial (read-only)
594591
A Boolean indicating whether this is an unofficial but common user
595592
modification to a system.

docs/source/luascript/ref-render.rst

+14-1
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,10 @@ manager.machine.video.snapshot_target
754754
Properties
755755
~~~~~~~~~~
756756

757+
target.ui_container (read-only)
758+
The :ref:`render container <luascript-ref-rendercontainer>` for drawing user
759+
interface elements over this render target, or ``nil`` for hidden render
760+
targets (targets that are not shown to the user directly).
757761
target.index (read-only)
758762
The 1-based index of the render target. This has O(n) complexity.
759763
target.width (read-only)
@@ -810,6 +814,9 @@ Instantiation
810814
manager.machine.render.ui_container
811815
Gets the render container used to draw the user interface, including menus,
812816
sliders and pop-up messages.
817+
manager.machine.render.targets[index].ui_container
818+
Gets the render container used to draw user interface elements over a
819+
particular render target.
813820
manager.machine.screens[tag].container
814821
Gets the render container used to draw a given screen.
815822

@@ -1145,10 +1152,16 @@ view.bounds (read-only)
11451152
effective bounds of the view in its current configuration. The coordinates
11461153
are in view units, which are arbitrary but assumed to have square aspect
11471154
ratio.
1148-
view.has_art
1155+
view.has_art (read-only)
11491156
A Boolean indicating whether the view has any non-screen items, including
11501157
items that are not visible because the user has hidden the item collection
11511158
that they belong to.
1159+
view.show_pointers (read/write)
1160+
A Boolean that sets whether mouse and pon pointers should be displayed for
1161+
the view.
1162+
view.hide_inactive_pointers (read/write)
1163+
A Boolean that sets whether mouse pointers for the view should be hidden
1164+
after a period of inactivity.
11521165

11531166

11541167
.. _luascript-ref-renderlayitem:

docs/source/techspecs/layout_files.rst

+5
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,11 @@ element. This means a view can reference elements and groups that appear after
690690
it in the file, and parameters from the enclosing scope will have their final
691691
values from the end of the ``mamelayout`` element.
692692

693+
A ``view`` element may have a ``showpointers`` attribute to set whether mouse
694+
and pen pointers should be shown for the view. If present, the value must be
695+
either ``yes`` or ``no``. If the ``showpointers`` attribute is not present, pen
696+
and mouse pointers are shown for views that contain items bound to I/O ports.
697+
693698
The following child elements are allowed inside a ``view`` element:
694699

695700
bounds

scripts/build/complay.py

+1
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ def layoutStartHandler(self, name, attrs):
409409
self.views[attrs['name']] = self.format_location()
410410
elif not self.VARPATTERN.match(attrs['name']):
411411
self.handle_error('Element view has duplicate name "%s" (previous %s)' % (attrs['name'], self.views[attrs['name']]))
412+
self.check_bool_attribute(name, attrs, 'showpointers', None)
412413
self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler))
413414
self.variable_scopes.append({ })
414415
self.item_ids = { }

src/emu/rendlay.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -4000,7 +4000,17 @@ layout_view::layout_view(
40004000
, m_elemmap(elemmap)
40014001
, m_defvismask(0U)
40024002
, m_has_art(false)
4003+
, m_show_ptr(false)
4004+
, m_ptr_time_out(true) // FIXME: add attribute for this
4005+
, m_exp_show_ptr(-1)
40034006
{
4007+
// check for explicit pointer display setting
4008+
if (viewnode.get_attribute_string_ptr("showpointers"))
4009+
{
4010+
m_show_ptr = env.get_attribute_bool(viewnode, "showpointers", false);
4011+
m_exp_show_ptr = m_show_ptr ? 1 : 0;
4012+
}
4013+
40044014
// parse the layout
40054015
m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0;
40064016
view_environment local(env, m_name.c_str());
@@ -4178,6 +4188,7 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
41784188
// loop over items and filter by visibility mask
41794189
bool first = true;
41804190
bool scrfirst = true;
4191+
bool haveinput = false;
41814192
for (item &curitem : m_items)
41824193
{
41834194
if ((visibility_mask & curitem.visibility_mask()) == curitem.visibility_mask())
@@ -4209,9 +4220,15 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
42094220
// accumulate interactive elements
42104221
if (!curitem.clickthrough() || curitem.has_input())
42114222
m_interactive_items.emplace_back(curitem);
4223+
if (curitem.has_input())
4224+
haveinput = true;
42124225
}
42134226
}
42144227

4228+
// if show pointers isn't explicitly, update it based on visible items
4229+
if (0 > m_exp_show_ptr)
4230+
m_show_ptr = haveinput;
4231+
42154232
// if we have an explicit bounds, override it
42164233
if (m_expbounds.x1 > m_expbounds.x0)
42174234
m_bounds = m_expbounds;
@@ -4282,6 +4299,29 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
42824299
}
42834300

42844301

4302+
//-------------------------------------------------
4303+
// set_show_pointers - set whether pointers
4304+
// should be displayed
4305+
//-------------------------------------------------
4306+
4307+
void layout_view::set_show_pointers(bool value) noexcept
4308+
{
4309+
m_show_ptr = value;
4310+
m_exp_show_ptr = value ? 1 : 0;
4311+
}
4312+
4313+
4314+
//-------------------------------------------------
4315+
// set_pointers_time_out - set whether pointers
4316+
// should be hidden after inactivity
4317+
//-------------------------------------------------
4318+
4319+
void layout_view::set_hide_inactive_pointers(bool value) noexcept
4320+
{
4321+
m_ptr_time_out = value;
4322+
}
4323+
4324+
42854325
//-------------------------------------------------
42864326
// set_prepare_items_callback - set handler called
42874327
// before adding items to render target

src/emu/rendlay.h

+9
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,12 @@ class layout_view
527527
const visibility_toggle_vector &visibility_toggles() const { return m_vistoggles; }
528528
u32 default_visibility_mask() const { return m_defvismask; }
529529
bool has_art() const { return m_has_art; }
530+
bool show_pointers() const { return m_show_ptr; }
531+
bool hide_inactive_pointers() const { return m_ptr_time_out; }
532+
533+
// setters
534+
void set_show_pointers(bool value) noexcept;
535+
void set_hide_inactive_pointers(bool value) noexcept ATTR_COLD;
530536

531537
// set handlers
532538
void set_prepare_items_callback(prepare_items_delegate &&handler) ATTR_COLD;
@@ -621,6 +627,9 @@ class layout_view
621627
render_bounds m_expbounds; // explicit bounds of the view
622628
u32 m_defvismask; // default visibility mask
623629
bool m_has_art; // true if the layout contains non-screen elements
630+
bool m_show_ptr; // whether pointers should be displayed
631+
bool m_ptr_time_out; // whether pointers should be hidden after inactivity
632+
s8 m_exp_show_ptr; // explicitly configured pointer visibility
624633
};
625634

626635

src/frontend/mame/luaengine.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -1502,7 +1502,6 @@ void lua_engine::initialize()
15021502
game_driver_type["no_cocktail"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_COCKTAIL) != 0; });
15031503
game_driver_type["is_bios_root"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::IS_BIOS_ROOT) != 0; });
15041504
game_driver_type["requires_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::REQUIRES_ARTWORK) != 0; });
1505-
game_driver_type["clickable_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::CLICKABLE_ARTWORK) != 0; });
15061505
game_driver_type["unofficial"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::UNOFFICIAL) != 0; });
15071506
game_driver_type["no_sound_hw"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_SOUND_HW) != 0; });
15081507
game_driver_type["mechanical"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::MECHANICAL) != 0; });

src/frontend/mame/luaengine_render.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,8 @@ void lua_engine::initialize_render(sol::table &emu)
994994
layout_view_type["effective_aspect"] = sol::property(&layout_view::effective_aspect);
995995
layout_view_type["bounds"] = sol::property(&layout_view::bounds);
996996
layout_view_type["has_art"] = sol::property(&layout_view::has_art);
997+
layout_view_type["show_pointers"] = sol::property(&layout_view::show_pointers, &layout_view::set_show_pointers);
998+
layout_view_type["hide_inactive_pointers"] = sol::property(&layout_view::hide_inactive_pointers, &layout_view::set_hide_inactive_pointers);
997999

9981000

9991001
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)
11001102

11011103

11021104
auto target_type = sol().registry().new_usertype<render_target>("target", sol::no_constructor);
1105+
target_type["ui_container"] = sol::property(&render_target::ui_container);
11031106
target_type["index"] = sol::property([] (render_target const &t) { return t.index() + 1; });
11041107
target_type["width"] = sol::property(&render_target::width);
11051108
target_type["height"] = sol::property(&render_target::height);

src/frontend/mame/ui/selmenu.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -4202,7 +4202,6 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
42024202

42034203
str << ((flags.machine_flags() & machine_flags::MECHANICAL) ? _("Mechanical System\tYes\n") : _("Mechanical System\tNo\n"));
42044204
str << ((flags.machine_flags() & machine_flags::REQUIRES_ARTWORK) ? _("Requires Artwork\tYes\n") : _("Requires Artwork\tNo\n"));
4205-
str << ((flags.machine_flags() & machine_flags::CLICKABLE_ARTWORK) ? _("Requires Clickable Artwork\tYes\n") : _("Requires Clickable Artwork\tNo\n"));
42064205
if (flags.machine_flags() & machine_flags::NO_COCKTAIL)
42074206
str << _("Support Cocktail\tNo\n");
42084207
str << ((flags.machine_flags() & machine_flags::IS_BIOS_ROOT) ? _("System is BIOS\tYes\n") : _("System is BIOS\tNo\n"));

src/frontend/mame/ui/ui.cpp

+29-19
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "render.h"
3939
#include "cheat.h"
4040
#include "rendfont.h"
41+
#include "rendlay.h"
4142
#include "romload.h"
4243
#include "screen.h"
4344
#include "speaker.h"
@@ -165,7 +166,13 @@ enum class mame_ui_manager::ui_callback_type : int
165166

166167
struct mame_ui_manager::active_pointer
167168
{
168-
active_pointer(ui_event const &event) : target(event.target), type(event.pointer_type), ptrid(event.pointer_id), x(-1.0F), y(-1.0F)
169+
active_pointer(ui_event const &event)
170+
: target(event.target)
171+
, updated(std::chrono::steady_clock::time_point::min())
172+
, type(event.pointer_type)
173+
, ptrid(event.pointer_id)
174+
, x(-1.0F)
175+
, y(-1.0F)
169176
{
170177
}
171178

@@ -175,6 +182,7 @@ struct mame_ui_manager::active_pointer
175182
}
176183

177184
render_target *target;
185+
std::chrono::steady_clock::time_point updated;
178186
osd::ui_event_handler::pointer type;
179187
u16 ptrid;
180188
float x, y;
@@ -198,8 +206,6 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
198206
, m_popup_text_end(0)
199207
, m_mouse_bitmap(32, 32)
200208
, m_mouse_arrow_texture(nullptr)
201-
, m_mouse_show(false)
202-
, m_update_pointers(false)
203209
, m_pointers_changed(false)
204210
, m_target_font_height(0)
205211
, m_has_warnings(false)
@@ -240,7 +246,6 @@ void mame_ui_manager::init()
240246
return 0;
241247
}));
242248
m_non_char_keys_down = std::make_unique<uint8_t[]>((std::size(non_char_keys) + 7) / 8);
243-
m_mouse_show = machine().system().flags & machine_flags::CLICKABLE_ARTWORK ? true : false;
244249

245250
// request notification callbacks
246251
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)
733738
// display the internal pointers
734739
bool const pointer_update = m_pointers_changed;
735740
m_pointers_changed = false;
736-
if (m_mouse_show || (is_menu_active() && machine().options().ui_mouse()))
741+
if (!is_menu_active() || machine().options().ui_mouse())
737742
{
738743
const float cursor_size = 0.6 * get_line_height();
739744
for (auto const &pointer : m_display_pointers)
@@ -1128,12 +1133,12 @@ void mame_ui_manager::process_ui_events()
11281133
{
11291134
if (osd::ui_event_handler::pointer::TOUCH != event.pointer_type)
11301135
{
1131-
m_update_pointers = true;
11321136
auto pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
11331137
if ((m_active_pointers.end() == pos) || (pos->target != event.target) || (pos->ptrid != event.pointer_id))
11341138
pos = m_active_pointers.emplace(pos, event);
11351139
else
11361140
assert(pos->type == event.pointer_type);
1141+
pos->updated = std::chrono::steady_clock::now();
11371142
event.target->map_point_container(event.pointer_x, event.pointer_y, *event.target->ui_container(), pos->x, pos->y);
11381143
}
11391144

@@ -1150,10 +1155,7 @@ void mame_ui_manager::process_ui_events()
11501155
{
11511156
auto const pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
11521157
if (m_active_pointers.end() != pos)
1153-
{
1154-
m_update_pointers = true;
11551158
m_active_pointers.erase(pos);
1156-
}
11571159

11581160
event.target->pointer_left(
11591161
event.pointer_type, event.pointer_id, event.pointer_device,
@@ -1168,10 +1170,7 @@ void mame_ui_manager::process_ui_events()
11681170
{
11691171
auto const pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
11701172
if (m_active_pointers.end() != pos)
1171-
{
1172-
m_update_pointers = true;
11731173
m_active_pointers.erase(pos);
1174-
}
11751174

11761175
event.target->pointer_aborted(
11771176
event.pointer_type, event.pointer_id, event.pointer_device,
@@ -1379,15 +1378,20 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
13791378

13801379
// process UI events and update pointers if necessary
13811380
process_ui_events();
1382-
if (m_update_pointers)
1381+
display_pointer_vector pointers;
1382+
pointers.reserve(m_active_pointers.size());
1383+
auto const now(std::chrono::steady_clock::now());
1384+
for (auto const &pointer : m_active_pointers)
13831385
{
1384-
display_pointer_vector pointers;
1385-
pointers.reserve(m_active_pointers.size());
1386-
for (auto const &pointer : m_active_pointers)
1387-
pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
1388-
set_pointers(pointers.begin(), pointers.end());
1389-
m_update_pointers = false;
1386+
layout_view const &view(pointer.target->current_view());
1387+
if (view.show_pointers())
1388+
{
1389+
// TODO: make timeout configurable
1390+
if (!view.hide_inactive_pointers() || (osd::ui_event_handler::pointer::PEN == pointer.type) || ((now - pointer.updated) <= std::chrono::seconds(3)))
1391+
pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
1392+
}
13901393
}
1394+
set_pointers(pointers.begin(), pointers.end());
13911395

13921396
if (!ui_disabled)
13931397
{
@@ -2400,6 +2404,12 @@ bool mame_ui_manager::set_ui_event_handler(std::function<bool ()> &&handler)
24002404
if (ui_callback_type::GENERAL != m_handler_callback_type)
24012405
return false;
24022406

2407+
for (auto *target = machine().render().first_target(); target; target = target->next())
2408+
{
2409+
if (!target->hidden())
2410+
target->forget_pointers();
2411+
}
2412+
24032413
set_handler(
24042414
ui_callback_type::CUSTOM,
24052415
handler_callback_func(

src/frontend/mame/ui/ui.h

-2
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,6 @@ class mame_ui_manager : public ui_manager
298298
display_pointer_vector m_display_pointers;
299299
bitmap_argb32 m_mouse_bitmap;
300300
render_texture * m_mouse_arrow_texture;
301-
bool m_mouse_show;
302-
bool m_update_pointers;
303301
bool m_pointers_changed;
304302

305303
ui_options m_ui_options;

0 commit comments

Comments
 (0)