From a5e6f4ea8d468f8f8e50ad5199a9f8aa9a81e9f1 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 27 Dec 2020 04:27:42 +1100 Subject: Expose a couple more things to Lua so the plugins can show the actual key mapped to UI clear. --- docs/source/techspecs/luaengine.rst | 31 ++++++++++++++++++------------- docs/source/techspecs/luareference.rst | 34 +++++++++++++++++++++++++++------- plugins/autofire/autofire_menu.lua | 6 ++++-- plugins/cheat/init.lua | 7 ++++--- src/frontend/mame/luaengine_input.cpp | 30 +++++++++++++++++++++++++----- 5 files changed, 78 insertions(+), 30 deletions(-) diff --git a/docs/source/techspecs/luaengine.rst b/docs/source/techspecs/luaengine.rst index d133ce1f51a..5d3565af214 100644 --- a/docs/source/techspecs/luaengine.rst +++ b/docs/source/techspecs/luaengine.rst @@ -35,25 +35,28 @@ Features The API is not yet complete, but this is a partial list of capabilities currently available to Lua scripts: -- machine metadata (app version, current emulated system, ROM details) -- machine control (starting, pausing, resetting, stopping) -- machine hooks (on frame painting and on user events) +- session information (app version, current emulated system, ROM details) +- session control (starting, pausing, resetting, stopping) +- event hooks (on frame painting and on user events) - device introspection (device tree listing, memory and register enumeration) - screen introspection (screens listing, screen details, frame counting) -- screen HUD drawing (text, lines, boxes on multiple screens) +- screen overlay drawing (text, lines, boxes on multiple screens) - memory read/write (8/16/32/64 bits, signed and unsigned) - register and state control (state enumeration, get and set) +Many of the classes are documented on the +:ref:`Lua class reference ` page. + .. _luaengine-usage: Usage ----- -MAME supports external scripting via Lua (>= 5.3) scripts, either written on the +MAME supports external scripting via Lua (>= 5.3) scripts, either entered at the interactive console or loaded as a file. To reach the console, enable the console plugin (e.g. run MAME with ``-plugin console``) and you will be greeted -by a ``[MAME]>`` prompt where you can enter your script. +with a ``[MAME]>`` prompt where you can enter Lua script interactively. To load a whole script at once, store it in a plain text file and pass it using ``-autoboot_script``. Please note that script loading may be delayed (a few @@ -71,7 +74,7 @@ hooks to be invoked on specific events (e.g. at each frame rendering). Walkthrough ----------- -Let's first run MAME in a terminal to reach the Lua console: +Let’s first run MAME in a terminal to reach the Lua console: :: @@ -95,14 +98,14 @@ Let's first run MAME in a terminal to reach the Lua console: [MAME]> -At this point, your game is probably running in demo mode, let's pause it: +At this point, your game is probably running in demo mode, let’s pause it: :: [MAME]> emu.pause() [MAME]> -Even without textual feedback on the console, you'll notice the game is now +Even without textual feedback on the console, you’ll notice the game is now paused. In general, commands are quiet and only print back error messages. You can check at runtime which version of MAME you are running, with: @@ -120,10 +123,12 @@ screens: [MAME]> for tag, screen in pairs(manager.machine.screens) do print(tag) end :screen -``manager.machine`` is the root object of your currently running machine: we -will be using this often. ``screens`` is a table with all available screens; -most machines only have one main screen. In our case, the main and only screen -is tagged as ``:screen``, and we can further inspect it: +``manager.machine`` is the :ref:`running machine ` +object for your current emulation session. We will be using this frequently. +``screens`` is a :ref:`device enumerator ` that yields +all emulated screens in the system; most arcade games only have one main screen. +In our case, the main and only screen is tagged as ``:screen``, and we can +further inspect it: :: diff --git a/docs/source/techspecs/luareference.rst b/docs/source/techspecs/luareference.rst index eacbdd0a05f..d15c74efe0b 100644 --- a/docs/source/techspecs/luareference.rst +++ b/docs/source/techspecs/luareference.rst @@ -1557,17 +1557,37 @@ Methods ioport:count_players() Returns the number of player controllers in the system. +ioport:type_pressed(type, [player]) + Returns a Boolean indicating whether the specified input is currently + pressed. The input port type is an enumerated value. The player number is + a zero-based index. If the player number is not supplied, it is assumed to + be zero. +ioport:type_name(type, [player]) + Returns the display name for the specified input type and player number. + The input type is an enumerated value. The player number is a zero-based + index. If the player number is not supplied, it is assumed to be zero. ioport:type_group(type, player) - Returns the I/O port group for the specified I/O port type and player - number. The I/O port type is an enumerated value. The player number is a - zero-based index. Returns an integer giving the grouping for the input. + Returns the input group for the specified input type and player number. The + input type is an enumerated value. The player number is a zero-based index. + Returns an integer giving the grouping for the input. If the player number + is not supplied, it is assumed to be zero. This should be called with values obtained from I/O port fields to provide canonical grouping in an input configuration UI. -ioport:type_seq(type, player, seqtype) - Get the configured input sequence for the specified input type, player and - sequence type. The sequence type must be ``"standard"``, ``"increment"`` - or ``"decrement"``. This provides access to general input configuration. +ioport:type_seq(type, [player], [seqtype]) + Get the configured input sequence for the specified input type, player + number and sequence type. The input type is an enumerated value. The + player number is a zero-based index. If the player number is not supplied, + it is assumed to be zero. If the sequence type is supplied, it must be + ``"standard"``, ``"increment"`` or ``"decrement"``; if it is not supplied, + it is assumed to be ``"standard"``. + + This provides access to general input configuration. +ioport:token_to_input_type(string) + Returns the input type and player number for the specified input type token. +ioport:input_type_to_token(type, [player]) + Returns the token string for the specified input type and player number. If + the player number is not supplied, it assumed to be zero. Properties ^^^^^^^^^^ diff --git a/plugins/autofire/autofire_menu.lua b/plugins/autofire/autofire_menu.lua index 14ad0ea0634..f234ab498ee 100644 --- a/plugins/autofire/autofire_menu.lua +++ b/plugins/autofire/autofire_menu.lua @@ -52,8 +52,11 @@ end -- Main menu local function populate_main_menu(buttons) + local ioport = manager.machine.ioport + local input = manager.machine.input local menu = {} menu[#menu + 1] = {_('Autofire buttons'), '', 'off'} + menu[#menu + 1] = {string.format(_('Press %s to delete'), input:seq_name(ioport:type_seq(ioport:token_to_input_type("UI_CLEAR")))), '', 'off'} menu[#menu + 1] = {'---', '', ''} header_height = #menu @@ -63,7 +66,7 @@ local function populate_main_menu(buttons) -- Round to two decimal places rate = math.floor(rate * 100) / 100 local text = button.button.name .. ' [' .. rate .. ' Hz]' - local subtext = manager.machine.input:seq_name(button.key) + local subtext = input:seq_name(button.key) menu[#menu + 1] = {text, subtext, ''} end content_height = #menu @@ -76,7 +79,6 @@ end local function handle_main_menu(index, event, buttons) local section, adjusted_index = menu_section(index) if section == MENU_SECTIONS.CONTENT then - manager.machine:popmessage(_('Press UI Clear to delete')) if event == 'select' then current_button = buttons[adjusted_index] table.insert(menu_stack, MENU_TYPES.EDIT) diff --git a/plugins/cheat/init.lua b/plugins/cheat/init.lua index 46a086f8ac2..4b409d1e029 100644 --- a/plugins/cheat/init.lua +++ b/plugins/cheat/init.lua @@ -604,8 +604,10 @@ function cheat.startplugin() local function menu_populate() local menu = {} if hotkeymenu then + local ioport = manager.machine.ioport + local input = manager.machine.input menu[1] = {_("Select cheat to set hotkey"), "", "off"} - menu[2] = {_("Press UI Clear to clear hotkey"), "", "off"} + menu[2] = {string.format(_("Press %s to clear hotkey"), input:seq_name(ioport:type_seq(ioport:token_to_input_type("UI_CLEAR")))), "", "off"} menu[3] = {"---", "", "off"} hotkeylist = {} @@ -615,7 +617,6 @@ function cheat.startplugin() return end - local input = manager.machine.input local poller = input:switch_sequence_poller() manager.machine:popmessage(_("Press button for hotkey or wait to leave unchanged")) manager.machine.video:frame_update() @@ -644,7 +645,7 @@ function cheat.startplugin() for num, cheat in ipairs(cheats) do if cheat.script then - menu[#menu + 1] = {cheat.desc, cheat.hotkeys and manager.machine.input:seq_name(cheat.hotkeys.keys) or _("None"), ""} + menu[#menu + 1] = {cheat.desc, cheat.hotkeys and input:seq_name(cheat.hotkeys.keys) or _("None"), ""} hotkeylist[#hotkeylist + 1] = function(event) return hkcbfunc(cheat, event) end end end diff --git a/src/frontend/mame/luaengine_input.cpp b/src/frontend/mame/luaengine_input.cpp index 2e13262db78..1dc0f491cb6 100644 --- a/src/frontend/mame/luaengine_input.cpp +++ b/src/frontend/mame/luaengine_input.cpp @@ -142,13 +142,33 @@ void lua_engine::initialize_input(sol::table &emu) auto ioport_manager_type = sol().registry().new_usertype("ioport", sol::no_constructor); ioport_manager_type["count_players"] = &ioport_manager::count_players; - ioport_manager_type["type_group"] = &ioport_manager::type_group; - ioport_manager_type["type_seq"] = - [] (ioport_manager &im, ioport_type type, int player, std::string const &seq_type_string) + ioport_manager_type["type_pressed"] = sol::overload( + &ioport_manager::type_pressed, + [] (ioport_manager &im, ioport_type type) { return im.type_pressed(type, 0); }); + ioport_manager_type["type_name"] = sol::overload( + &ioport_manager::type_name, + [] (ioport_manager &im, ioport_type type) { return im.type_name(type, 0); }); + ioport_manager_type["type_group"] = sol::overload( + &ioport_manager::type_group, + [] (ioport_manager &im, ioport_type type) { return im.type_group(type, 0); }); + ioport_manager_type["type_seq"] = sol::overload( + [] (ioport_manager &im, ioport_type type, int player, char const *seq_type_string) + { + input_seq_type seq_type = s_seq_type_parser(seq_type_string); + return im.type_seq(type, player, seq_type); + }, + [] (ioport_manager &im, ioport_type type, int player) { return im.type_seq(type, player, SEQ_TYPE_STANDARD); }, + [] (ioport_manager &im, ioport_type type) { return im.type_seq(type, 0, SEQ_TYPE_STANDARD); }); + ioport_manager_type["token_to_input_type"] = + [] (ioport_manager &im, std::string const &string) { - input_seq_type seq_type = s_seq_type_parser(seq_type_string); - return im.type_seq(type, player, seq_type); + int player; + ioport_type const type = im.token_to_input_type(string.c_str(), player); + return std::make_tuple(type, player); }; + ioport_manager_type["input_type_to_token"] = sol::overload( + &ioport_manager::input_type_to_token, + [] (ioport_manager &im, ioport_type type) { return im.input_type_to_token(type, 0); }); ioport_manager_type["ports"] = sol::property([] (ioport_manager &im) { return tag_object_ptr_map(im.ports()); }); ioport_manager_type["natkeyboard"] = sol::property(&ioport_manager::natkeyboard); -- cgit v1.2.3