Input refactoring:

osd/modules/input, emu/inpttype.cpp: Made most default joystick
assignments supplied by input modules.  Input modules take available
controls into consideration when generating default assignments.

emu/inpttype.ipp: Added a separate "Back" UI input separate from Cancel.
You may want an easier to hit combination for moving to the previous
menu than for exiting or cancelling input.  They both default to Escape.

emu/inpttype.ipp: Added a UI Help control.  Currently only used by
analog inputs menu

emu/inpttype.h: Moved I/O port field type enum to its own header and
sorted UI controls so they appear in a more logical order.

ui: Don't use UI Select to restore defaults - people should be getting
used to the UI Clear input by now.  UI Select cycles multi-value items
instead.

ui/inputmap.cpp: Don't use immediate cancel to cycle between clearing
and restoring default assignment (use UI Clear instead).

osd: Reduced the number of files needing to include the dreaded emu.h.
Got some implementation out of headers.
This commit is contained in:
Vas Crabb 2023-02-18 06:18:45 +11:00
parent 20d7135179
commit d4589e0b29
109 changed files with 36509 additions and 31293 deletions

View File

@ -25,12 +25,21 @@
<newseq type="standard">KEYCODE_ENTER OR KEYCODE_LCONTROL</newseq>
</port>
<port type="UI_CONFIGURE">
<port type="UI_MENU">
<newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_3</newseq>
</port>
<port type="UI_BACK">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_LALT OR JOYCODE_1_BUTTON2</newseq>
</port>
<port type="UI_CANCEL">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_2 KEYCODE_4</newseq>
</port>
<port type="UI_CLEAR">
<newseq type="standard">KEYCODE_DEL OR KEYCODE_SPACE OR JOYCODE_1_BUTTON3</newseq>
</port>
<port type="UI_HELP">
<newseq type="standard">KEYCODE_F1 OR KEYCODE_LSHIFT OR JOYCODE_1_BUTTON4</newseq>
</port>
<port type="START1">
<newseq type="standard">KEYCODE_1</newseq>

View File

@ -25,12 +25,21 @@
<newseq type="standard">KEYCODE_ENTER OR KEYCODE_LCONTROL</newseq>
</port>
<port type="UI_CONFIGURE">
<port type="UI_MENU">
<newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_3</newseq>
</port>
<port type="UI_BACK">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_LALT OR JOYCODE_1_BUTTON2</newseq>
</port>
<port type="UI_CANCEL">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_2 KEYCODE_4</newseq>
</port>
<port type="UI_CLEAR">
<newseq type="standard">KEYCODE_DEL OR KEYCODE_SPACE OR JOYCODE_1_BUTTON3</newseq>
</port>
<port type="UI_HELP">
<newseq type="standard">KEYCODE_F1 OR KEYCODE_LSHIFT OR JOYCODE_1_BUTTON4</newseq>
</port>
<port type="START1">
<newseq type="standard">KEYCODE_1</newseq>

View File

@ -27,12 +27,21 @@
<newseq type="standard">KEYCODE_ENTER OR KEYCODE_LCONTROL</newseq>
</port>
<port type="UI_CONFIGURE">
<port type="UI_MENU">
<newseq type="standard">KEYCODE_TAB</newseq>
</port>
<port type="UI_BACK">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_LALT OR JOYCODE_1_BUTTON2</newseq>
</port>
<port type="UI_CANCEL">
<newseq type="standard">KEYCODE_ESC</newseq>
</port>
<port type="UI_CLEAR">
<newseq type="standard">KEYCODE_DEL OR KEYCODE_SPACE OR JOYCODE_1_BUTTON3</newseq>
</port>
<port type="UI_HELP">
<newseq type="standard">KEYCODE_F1 OR KEYCODE_C OR JOYCODE_1_BUTTON4</newseq>
</port>
<port type="START1">
<newseq type="standard">KEYCODE_1</newseq>

View File

@ -32,12 +32,21 @@
<newseq type="standard">KEYCODE_7 OR KEYCODE_ENTER OR JOYCODE_1_BUTTON1</newseq>
</port>
<port type="UI_CONFIGURE">
<port type="UI_MENU">
<newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_5</newseq>
</port>
<port type="UI_BACK">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_H OR JOYCODE_1_BUTTON2 OR KEYCODE_L</newseq>
</port>
<port type="UI_CANCEL">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_2 KEYCODE_6</newseq>
</port>
<port type="UI_CLEAR">
<newseq type="standard">KEYCODE_DEL OR KEYCODE_9 OR JOYCODE_1_BUTTON3</newseq>
</port>
<port type="UI_HELP">
<newseq type="standard">KEYCODE_F1 OR KEYCODE_0 OR JOYCODE_1_BUTTON4</newseq>
</port>
<port type="START1">
<newseq type="standard">KEYCODE_1 OR JOYCODE_1_START</newseq>

View File

@ -25,12 +25,21 @@
<newseq type="standard">KEYCODE_ENTER OR KEYCODE_LCONTROL</newseq>
</port>
<port type="UI_CONFIGURE">
<port type="UI_MENU">
<newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_3</newseq>
</port>
<port type="UI_BACK">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_LALT OR JOYCODE_1_BUTTON2</newseq>
</port>
<port type="UI_CANCEL">
<newseq type="standard">KEYCODE_ESC OR KEYCODE_2 KEYCODE_4</newseq>
</port>
<port type="UI_CLEAR">
<newseq type="standard">KEYCODE_DEL OR KEYCODE_SPACE OR JOYCODE_1_BUTTON3</newseq>
</port>
<port type="UI_HELP">
<newseq type="standard">KEYCODE_F1 OR KEYCODE_LSHIFT OR JOYCODE_1_BUTTON4</newseq>
</port>
<port type="START1">
<newseq type="standard">KEYCODE_1</newseq>

View File

@ -155,7 +155,7 @@ bgfx_screen_chains
we want to give each player their own full screen display (two physical
monitors) along with the LCD, well go with::
-numscreens 2 -view0 "Player 1" -view1 "Player 2" -video bgfx -bgfx_screen_chains hlsl,unfiltered,unfiltered:hlsl,unfiltered,unfiltered
-numscreens 2 -view0 "Player 1" -view1 "Player 2" -video bgfx -bgfx_screen_chains hlsl,unfiltered:hlsl,unfiltered
This sets up the view for each display respectively, keeping HLSL effect on
the CRT for each window (physical display) while going unfiltered for the
@ -164,8 +164,7 @@ bgfx_screen_chains
If using only one window (one display), keep in mind the game still has
three screens, so we would use::
bgfx_screen_chains hlsl,unfiltered,unfiltered``
bgfx_screen_chains hlsl,unfiltered,unfiltered
Note that the commas are on the outside edges, and any colons are in the
middle.
@ -177,9 +176,6 @@ bgfx_shadow_mask
Tweaking BGFX HLSL Settings inside MAME
---------------------------------------
*Warning: Currently BGFX HLSL settings are not saved or loaded from any
configuration files. This is expected to change in the future.*
Start by loading MAME with the game of your choice (e.g. **mame pacman**).
The tilde key (**~**) brings up the on-screen display options. Use up and down
@ -189,6 +185,12 @@ these settings.
Note that settings are individually changeable on a per-screen basis.
BGFX slider settings are saved per-system in CFG files. If the
``bgfx_screen_chains`` setting has been set (either in an INI file or on the
command line), it will set the initial effects. If the ``bgfx_screen_chains``
setting has not been set, MAME will use the effects you chose the last time you
ran the system.
Using the included pillarbox filters
------------------------------------

View File

@ -147,7 +147,7 @@ override the default control assignments for emulated inputs by type:
.. code-block:: XML
<input>
<port type="UI_CONFIGURE">
<port type="UI_MENU">
<newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_5</newseq>
</port>
<port type="UI_CANCEL">
@ -170,7 +170,7 @@ override the default control assignments for emulated inputs by type:
This sets the following default input assignments:
Config Menu (User Interface)
Show/Hide Menu (User Interface)
Tab key, or 1 and 2 keys pressed simultaneously
UI Cancel (User Interface)
Escape key, or 2 and 6 keys pressed simultaneously

View File

@ -66,10 +66,10 @@ Experiment with different values to get the best effect.
When adding a new autofire button, there is a **Cancel** option that changes to
**Create** after you set the input and hotkey. Select **Create** to finish
creating the autofire button and return to the list of autofire buttons. The
new autofire button will be added at the end of the list. Press the UI Cancel
key (Escape/Esc on the keyboard by default), or select **Cancel** before setting
the input/hotkey, to return to the previous menu without creating the new
autofire button.
new autofire button will be added at the end of the list. Press the UI Back key
(Escape/Esc on the keyboard by default), or select **Cancel** before setting the
input/hotkey, to return to the previous menu without creating the new autofire
button.
When modifying an existing autofire button, select **Done** or press the UI
Cancel key to return to the list of autofire buttons. Changes take effect

View File

@ -55,7 +55,7 @@ whole:
descriptive. Press the UI Select key (Return/Enter on the keyboard or the
first button on the first joystick by default) to edit the current name, or
press the UI Clear key to type a new name. Press the UI Select key before
moving to another menu item to save the new name; press the UI Cancel key
moving to another menu item to save the new name; press the UI Back key
(Escape/Esc on the keyboard by default) to change discard the new name.
* Select **Activation combination** to set the control (or combination of
controls) you want to use to activate the macro. Keep in mind that regular
@ -112,11 +112,11 @@ When creating a new macro, there is a **Cancel** option that changes to
**Create** after you set the activating sequence and the first input for the
initially created step. Select **Create** to finish creating the macro and
return to the list of input macros. The new macro will be added at the end of
the list. Press the UI Cancel key, or select **Cancel** before setting the
the list. Press the UI Back key, or select **Cancel** before setting the
activation sequence/input, to return to the previous menu without creating the
new macro.
When editing an existing macro, select **Done** or press the UI Cancel key to
When editing an existing macro, select **Done** or press the UI Back key to
return to the list of input macros. Changes take effect immediately.

View File

@ -2549,6 +2549,10 @@ manager.machine.uiinput
Methods
^^^^^^^
uiinput:reset()
Clears pending events and UI input states. Should be called when leaving a
modal state where input is handled directly (e.g. configuring an input
combination).
uiinput:find_mouse()
Returns host system mouse pointer X position, Y position, button state, and
the :ref:`render target <luareference-render-target>` it falls in. The

View File

@ -12,17 +12,18 @@ Introduction
------------
To show the :ref:`main menu <menus-main>` while running an emulated system in
MAME, press the **Config Menu** key or button (**Tab** by default). If the
emulated system has keyboard inputs, you may need to press the **UI Toggle** key
or button (**Scroll Lock**, or **Forward Delete** on macOS, by default) to
enable user interface controls first. You can dismiss a menu by pressing the
**UI Cancel** key or button (**Escape** by default). Dismissing a menu will
return to its parent menu, or to the running system in the case of the main
menu.
MAME, press the **Show/Hide Menu** key or button (**Tab** by default). If the
emulated system has keyboard inputs, you may need to press the
**Toggle UI Controls** key or button (**Scroll Lock**, or **Forward Delete** on
macOS, by default) to enable user interface controls first. You can dismiss a
menu by pressing the **UI Back** key or button (**Escape** by default).
Dismissing a menu will return to its parent menu, or to the running system in
the case of the main menu.
You can hide a menu and return to the running system by pressing the **Config
Menu** key or button. Pressing the **Config Menu** key or button again will
jump back to the same menu. This is useful when testing changes to settings.
You can hide a menu and return to the running system by pressing the
**Show/Hide Menu** key or button. Pressing the **Show/Hide Menu** key or button
again will jump back to the same menu. This is useful when testing changes to
settings.
Emulated system inputs are ignored while menus are displayed. You can still
pause or resume the running system while most menus are displayed by pressing
@ -43,17 +44,17 @@ For more information on navigating menus, :ref:`see the relevant section
Main menu
---------
The main menu is shown when you press the **Config Menu** key or button while
The main menu is shown when you press the **Show/Hide Menu** key or button while
running an emulated system or while the system information screen is displayed.
It provides access to menus used to change settings, control various features,
and show information about the running system and MAME itself.
If you press the **Config Menu** key or button to show the main menu while the
system information screen is displayed, the emulated system will not start until
the main menu is dismissed (either by selecting **Start System**, pressing the
**UI Cancel** key or button, or pressing the **Config Menu** key or button).
This can be useful for mounting media images or changing DIP switches and
machine configuration settings before the emulated system starts.
If you press the **Show/Hide Menu** key or button to show the main menu while
the system information screen is displayed, the emulated system will not start
until the main menu is dismissed (either by selecting **Start System**, pressing
the **UI Back** key or button, or pressing the **Show/Hide Menu** key or
button). This can be useful for mounting media images or changing DIP switches
and machine configuration settings before the emulated system starts.
Input Settings
Shows the :ref:`Input Settings <menus-inputopts>` menu, where you can assign
@ -127,13 +128,13 @@ Cheat
Plugin Options
Shows the Plugin Options menu, where you can access settings for enabled
plugins. This item is not shown if no plugins are enabled, or if the main
menu is shown before the emulated system starts (by pressing the Config Menu
key/button while the system information screen is displayed).
menu is shown before the emulated system starts (by pressing the Show/Hide
Menu key/button while the system information screen is displayed).
External DAT View
Shows the info viewer, which displays information loaded from various
external support files. This item is not shown if the :ref:`data plugin
<plugins-data>` is not enabled, or if the main menu is shown before the
emulated system starts (by pressing the Config Menu key/button while the
emulated system starts (by pressing the Show/Hide Menu key/button while the
system information screen is displayed).
Add To Favorites/Remove From Favorites
Adds the running system to the favourites list, or removes it if its
@ -144,13 +145,13 @@ About MAME
Select New System
Shows the system selection menu, where you can select a system to start a
new emulation session. This item is not shown if the main menu is shown
before the emulated system starts (by pressing the Config Menu key/button
before the emulated system starts (by pressing the Show/Hide Menu key/button
while the system information screen is displayed).
Close Menu/Start System
Closes the main menu, returning control of the running system. Shows
**Start System** if the main menu is shown before the emulated system
starts (by pressing the Config Menu key/button while the system information
screen is displayed).
starts (by pressing the Show/Hide Menu key/button while the system
information screen is displayed).
.. _menus-inputopts:

View File

@ -20,13 +20,13 @@ The default settings for the most important controls to know when running an
emulated system, and the settings they correspond to in case you want to change
them, are as follows:
Scroll Lock, or Forward Delete on macOS (UI Toggle)
Scroll Lock, or Forward Delete on macOS (Toggle UI Controls)
For emulated systems with keyboard inputs, enable or disable UI controls.
(MAME starts with UI controls disabled for systems with keyboard inputs
unless the :ref:`ui_active option <mame-commandline-uiactive>` is on.)
Tab (Config Menu)
Tab (Show/Hide Menu)
Show or hide the menu during emulation.
Escape (UI Cancel)
Escape (UI Back and UI Cancel)
Return to the system selection menu, or exit if MAME was started with a
system specified (from the command line or using an
:ref:`external front-end <frontends>`).
@ -60,7 +60,7 @@ Return/Enter keypad Enter (UI Select)
Select the highlighted menu item.
Forward Delete, or Fn+Delete on some compact keyboards (UI Clear)
Clear setting or reset to default value.
Escape (UI Cancel)
Escape (UI Back and UI Cancel)
Clear the search if searching the menu, otherwise close the menu, returning
to the previous menu, or returning to the emulated system in the case of the
main menu (theres usually an item at the bottom of the menu for the same
@ -92,18 +92,24 @@ most important UI controls have joystick assignments by default:
* Move the first joystick left or right in the X axis to adjust settings.
* Press the first button on the first joystick to select the highlighted menu
item.
* If the first joystick has at least three buttons, press the second button on
the first joystick to close the menu, returning to the previous menu, or
returning to the emulated system in the case of the main menu (theres usually
an item at the bottom of the menu for the same purpose).
For gamepad-style controllers, the left analog thumb stick usually controls UI
navigation. You may find it convenient to assign directional pad controls to UI
navigation in addition to or in place of the left thumb stick.
For gamepad-style controllers, the left analog thumb stick and directional pad
usually control UI navigation. Depending on the controller, the right analog
thumb stick, triggers and additional buttons may automatically be assigned to UI
inputs. Check the **User Interface** input assignments menu to see how controls
are assigned.
If you want to be able to use MAME with a game controller without needing a
keyboard, youll need to assign joystick buttons (or combinations of buttons) to
these controls as well:
* **Config Menu** to show or dismiss the menu during emulation
* **UI Cancel** to close menus, return to the system selection menu, or exit
MAME
* **Show/Hide Menu** to show or hide the menu during emulation
* **UI Back** to close menus
* **UI Cancel** to return to the system selection menu or exit MAME
* **UI Clear** isnt essential for basic emulation, but its used to clear or
reset some settings to defaults
* **UI Home**, **UI End**, **UI Page Up**, **UI Page Down**, **UI Previous
@ -138,8 +144,8 @@ pointing device:
* Click toolbar items to select them, or hover over them to see a description.
If you have enough additional mouse buttons, you may want to assign button
combinations to the **Config Menu**, **Pause** and/or **UI Cancel** inputs to
make it possible to use MAME without a keyboard.
combinations to the **Show/Hide Menu**, **Pause**, **UI Back** and/or
**UI Cancel** inputs to make it possible to use MAME without a keyboard.
.. _ui-inptcfg:
@ -220,10 +226,7 @@ input or a combination of inputs for a logical **and** operation:
* Press a key or button or move an analog control twice to add a **not** item to
the **and** operation. Pressing the same key or button or moving the same
analog control additional times toggles the **not** on and off.
* Pressing **UI Cancel** (**Escape** by default) *before* activating any other
controls clears the setting or restores the default assignment.
* Press **UI Cancel** *after* activating another control to leave the setting
unchanged.
* Press **UI Cancel** (**Escape** by default) to leave the setting unchanged.
* The new setting is shown below the menu. Wait one second after activating an
input to accept the new setting.
@ -344,10 +347,7 @@ When you select an axis setting, MAME will wait for you to enter an input:
direction of the control on or off.
* When appending to a setting, move an analog control other than the last
assigned control or press a key or button to add an **or** operation.
* Pressing **UI Cancel** (**Escape** by default) *before* activating any other
controls clears the setting or restores the default assignment.
* Pressing **UI Cancel** *after* activating another control leaves the setting
unchanged.
* Pressing **UI Cancel** (**Escape** by default) leaves the setting unchanged.
* The new setting is shown below the menu. Wait one second after moving an
analog control to accept the new setting.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -248,7 +248,7 @@ end
local function handle_edit_menu(index, event, buttons)
local section, adjusted_index = menu_section(index)
if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'cancel') then
if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'back') then
configure_menu_active = false
table.remove(menu_stack)
return true
@ -285,7 +285,7 @@ end
local function handle_add_menu(index, event, buttons)
local section, adjusted_index = menu_section(index)
if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'cancel') then
if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'back') then
configure_menu_active = false
table.remove(menu_stack)
if is_button_complete(current_button) and (event == 'select') then

View File

@ -714,7 +714,7 @@ function cheat.startplugin()
local function menu_callback(index, event)
manager.machine:popmessage()
if hotkeymenu then
if event == "cancel" then
if event == "back" then
hotkeymenu = false
return true
else

View File

@ -1044,7 +1044,7 @@ function cheatfind.startplugin()
end
local function menu_callback(index, event)
if event == "cancel" and pausesel == 1 then
if event == "back" and pausesel == 1 then
emu.unpause()
menu_is_showing = false
return false -- return false so menu will be popped off the stack

View File

@ -106,7 +106,7 @@ function commonui.input_selection_menu(action, title, filter)
function menu:handle(index, event)
local selection
if (event == 'cancel') or ((index == input_item_cancel) and (event == 'select')) then
if (event == 'back') or ((index == input_item_cancel) and (event == 'select')) then
action(nil)
return true
elseif event == 'select' then
@ -177,16 +177,18 @@ function commonui.switch_polling_helper(starting_sequence)
if uiinput:pressed(cancel) then
-- UI_CANCEL pressed, abort
machine:popmessage()
uiinput:reset()
if (not poller.modified) or (modified_ticks == emu.osd_ticks()) then
-- cancelled immediately
self.sequence = nil
return true -- TODO: communicate this better?
self.sequence = nil -- TODO: communicate this better?
return true
else
-- entered something before cancelling
self.sequence = nil
return true
end
elseif poller:poll() then
uiinput:reset()
if poller.valid then
-- valid sequence entered
machine:popmessage()

View File

@ -160,6 +160,8 @@ local function handle_edit_items(index, event)
end
edit_name_buffer = nil
return true
elseif event == 'back' then
return true -- swallow back while editing text
elseif event == 'cancel' then
edit_name_buffer = nil
return true
@ -434,7 +436,7 @@ local function handle_add(index, event)
local handled, selection = handle_edit_items(index, event)
if handled then
return true, selection
elseif event == 'cancel' then
elseif event == 'back' then
edit_current_macro = nil
edit_menu_active = false
edit_items = nil
@ -458,7 +460,7 @@ local function handle_edit(index, event)
local handled, selection = handle_edit_items(index, event)
if handled then
return true, selection
elseif (event == 'cancel') or ((index == edit_item_exit) and (event == 'select')) then
elseif (event == 'back') or ((index == edit_item_exit) and (event == 'select')) then
edit_current_macro = nil
edit_menu_active = false
edit_items = nil

View File

@ -161,6 +161,7 @@ files {
MAME_DIR .. "src/emu/ioport.cpp",
MAME_DIR .. "src/emu/ioport.h",
MAME_DIR .. "src/emu/inpttype.ipp",
MAME_DIR .. "src/emu/inpttype.h",
MAME_DIR .. "src/emu/logmacro.h",
MAME_DIR .. "src/emu/machine.cpp",
MAME_DIR .. "src/emu/machine.h",

View File

@ -76,6 +76,8 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/modules/font/font_osx.cpp",
MAME_DIR .. "src/osd/modules/font/font_sdl.cpp",
MAME_DIR .. "src/osd/modules/font/font_windows.cpp",
MAME_DIR .. "src/osd/modules/input/assignmenthelper.cpp",
MAME_DIR .. "src/osd/modules/input/assignmenthelper.h",
MAME_DIR .. "src/osd/modules/input/input_common.cpp",
MAME_DIR .. "src/osd/modules/input/input_common.h",
MAME_DIR .. "src/osd/modules/input/input_dinput.cpp",

351
src/emu/inpttype.h Normal file
View File

@ -0,0 +1,351 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
inpttype.ipp
Core-defined input types.
***************************************************************************/
#ifndef MAME_EMU_INPTTYPE_H
#define MAME_EMU_INPTTYPE_H
#pragma once
#include "interface/inputfwd.h"
#include "osdcomm.h"
enum ioport_type : osd::u32
{
// pseudo-port types
IPT_INVALID = 0,
IPT_UNUSED,
IPT_END,
IPT_UNKNOWN,
IPT_PORT,
IPT_DIPSWITCH,
IPT_CONFIG,
// start buttons
IPT_START1,
IPT_START2,
IPT_START3,
IPT_START4,
IPT_START5,
IPT_START6,
IPT_START7,
IPT_START8,
IPT_START9,
IPT_START10,
// coin slots
IPT_COIN1,
IPT_COIN2,
IPT_COIN3,
IPT_COIN4,
IPT_COIN5,
IPT_COIN6,
IPT_COIN7,
IPT_COIN8,
IPT_COIN9,
IPT_COIN10,
IPT_COIN11,
IPT_COIN12,
IPT_BILL1,
// service coin
IPT_SERVICE1,
IPT_SERVICE2,
IPT_SERVICE3,
IPT_SERVICE4,
// tilt inputs
IPT_TILT1,
IPT_TILT2,
IPT_TILT3,
IPT_TILT4,
// misc other digital inputs
IPT_POWER_ON,
IPT_POWER_OFF,
IPT_SERVICE,
IPT_TILT,
IPT_INTERLOCK,
IPT_MEMORY_RESET,
IPT_VOLUME_UP,
IPT_VOLUME_DOWN,
IPT_START, // use the numbered start button(s) for coin-ops
IPT_SELECT,
IPT_KEYPAD,
IPT_KEYBOARD,
// digital joystick inputs
IPT_DIGITAL_JOYSTICK_FIRST,
// use IPT_JOYSTICK for panels where the player has one single joystick
IPT_JOYSTICK_UP,
IPT_JOYSTICK_DOWN,
IPT_JOYSTICK_LEFT,
IPT_JOYSTICK_RIGHT,
// use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels
IPT_JOYSTICKRIGHT_UP,
IPT_JOYSTICKRIGHT_DOWN,
IPT_JOYSTICKRIGHT_LEFT,
IPT_JOYSTICKRIGHT_RIGHT,
IPT_JOYSTICKLEFT_UP,
IPT_JOYSTICKLEFT_DOWN,
IPT_JOYSTICKLEFT_LEFT,
IPT_JOYSTICKLEFT_RIGHT,
IPT_DIGITAL_JOYSTICK_LAST,
// action buttons
IPT_BUTTON1,
IPT_BUTTON2,
IPT_BUTTON3,
IPT_BUTTON4,
IPT_BUTTON5,
IPT_BUTTON6,
IPT_BUTTON7,
IPT_BUTTON8,
IPT_BUTTON9,
IPT_BUTTON10,
IPT_BUTTON11,
IPT_BUTTON12,
IPT_BUTTON13,
IPT_BUTTON14,
IPT_BUTTON15,
IPT_BUTTON16,
// mahjong inputs
IPT_MAHJONG_FIRST,
IPT_MAHJONG_A,
IPT_MAHJONG_B,
IPT_MAHJONG_C,
IPT_MAHJONG_D,
IPT_MAHJONG_E,
IPT_MAHJONG_F,
IPT_MAHJONG_G,
IPT_MAHJONG_H,
IPT_MAHJONG_I,
IPT_MAHJONG_J,
IPT_MAHJONG_K,
IPT_MAHJONG_L,
IPT_MAHJONG_M,
IPT_MAHJONG_N,
IPT_MAHJONG_O,
IPT_MAHJONG_P,
IPT_MAHJONG_Q,
IPT_MAHJONG_KAN,
IPT_MAHJONG_PON,
IPT_MAHJONG_CHI,
IPT_MAHJONG_REACH,
IPT_MAHJONG_RON,
IPT_MAHJONG_FLIP_FLOP,
IPT_MAHJONG_BET,
IPT_MAHJONG_SCORE,
IPT_MAHJONG_DOUBLE_UP,
IPT_MAHJONG_BIG,
IPT_MAHJONG_SMALL,
IPT_MAHJONG_LAST_CHANCE,
IPT_MAHJONG_LAST,
// hanafuda inputs
IPT_HANAFUDA_FIRST,
IPT_HANAFUDA_A,
IPT_HANAFUDA_B,
IPT_HANAFUDA_C,
IPT_HANAFUDA_D,
IPT_HANAFUDA_E,
IPT_HANAFUDA_F,
IPT_HANAFUDA_G,
IPT_HANAFUDA_H,
IPT_HANAFUDA_YES,
IPT_HANAFUDA_NO,
IPT_HANAFUDA_LAST,
// gambling inputs
IPT_GAMBLING_FIRST,
IPT_GAMBLE_KEYIN, // attendant
IPT_GAMBLE_KEYOUT, // attendant
IPT_GAMBLE_SERVICE, // attendant
IPT_GAMBLE_BOOK, // attendant
IPT_GAMBLE_DOOR, // attendant
// IPT_GAMBLE_DOOR2, // many gambling games have several doors.
// IPT_GAMBLE_DOOR3,
// IPT_GAMBLE_DOOR4,
// IPT_GAMBLE_DOOR5,
IPT_GAMBLE_PAYOUT, // player
IPT_GAMBLE_BET, // player
IPT_GAMBLE_DEAL, // player
IPT_GAMBLE_STAND, // player
IPT_GAMBLE_TAKE, // player
IPT_GAMBLE_D_UP, // player
IPT_GAMBLE_HALF, // player
IPT_GAMBLE_HIGH, // player
IPT_GAMBLE_LOW, // player
// poker-specific inputs
IPT_POKER_HOLD1,
IPT_POKER_HOLD2,
IPT_POKER_HOLD3,
IPT_POKER_HOLD4,
IPT_POKER_HOLD5,
IPT_POKER_CANCEL,
// slot-specific inputs
IPT_SLOT_STOP1,
IPT_SLOT_STOP2,
IPT_SLOT_STOP3,
IPT_SLOT_STOP4,
IPT_SLOT_STOP_ALL,
IPT_GAMBLING_LAST,
// analog inputs
IPT_ANALOG_FIRST,
IPT_ANALOG_ABSOLUTE_FIRST,
IPT_AD_STICK_X, // absolute // autocenter
IPT_AD_STICK_Y, // absolute // autocenter
IPT_AD_STICK_Z, // absolute // autocenter
IPT_PADDLE, // absolute // autocenter
IPT_PADDLE_V, // absolute // autocenter
IPT_PEDAL, // absolute // autocenter
IPT_PEDAL2, // absolute // autocenter
IPT_PEDAL3, // absolute // autocenter
IPT_LIGHTGUN_X, // absolute
IPT_LIGHTGUN_Y, // absolute
IPT_POSITIONAL, // absolute // autocenter if not wraps
IPT_POSITIONAL_V, // absolute // autocenter if not wraps
IPT_ANALOG_ABSOLUTE_LAST,
IPT_DIAL, // relative
IPT_DIAL_V, // relative
IPT_TRACKBALL_X, // relative
IPT_TRACKBALL_Y, // relative
IPT_MOUSE_X, // relative
IPT_MOUSE_Y, // relative
IPT_ANALOG_LAST,
// analog adjuster support
IPT_ADJUSTER,
// the following are special codes for user interface handling - not to be used by drivers!
IPT_UI_FIRST,
IPT_UI_MENU,
IPT_UI_SELECT,
IPT_UI_BACK,
IPT_UI_CANCEL,
IPT_UI_CLEAR,
IPT_UI_HELP,
IPT_UI_UP,
IPT_UI_DOWN,
IPT_UI_LEFT,
IPT_UI_RIGHT,
IPT_UI_HOME,
IPT_UI_END,
IPT_UI_PAGE_UP,
IPT_UI_PAGE_DOWN,
IPT_UI_PREV_GROUP,
IPT_UI_NEXT_GROUP,
IPT_UI_ON_SCREEN_DISPLAY,
IPT_UI_TOGGLE_UI,
IPT_UI_DEBUG_BREAK,
IPT_UI_PAUSE,
IPT_UI_PAUSE_SINGLE,
IPT_UI_REWIND_SINGLE,
IPT_UI_SAVE_STATE,
IPT_UI_LOAD_STATE,
IPT_UI_RESET_MACHINE,
IPT_UI_SOFT_RESET,
IPT_UI_SHOW_GFX,
IPT_UI_FRAMESKIP_DEC,
IPT_UI_FRAMESKIP_INC,
IPT_UI_THROTTLE,
IPT_UI_FAST_FORWARD,
IPT_UI_SHOW_FPS,
IPT_UI_SNAPSHOT,
IPT_UI_RECORD_MNG,
IPT_UI_RECORD_AVI,
IPT_UI_TOGGLE_CHEAT,
IPT_UI_DISPLAY_COMMENT,
IPT_UI_ZOOM_IN,
IPT_UI_ZOOM_OUT,
IPT_UI_ZOOM_DEFAULT,
IPT_UI_ROTATE,
IPT_UI_SHOW_PROFILER,
IPT_UI_RELEASE_POINTER,
IPT_UI_PASTE,
IPT_UI_TAPE_START,
IPT_UI_TAPE_STOP,
IPT_UI_FOCUS_NEXT,
IPT_UI_FOCUS_PREV,
IPT_UI_DATS,
IPT_UI_FAVORITES,
IPT_UI_EXPORT,
IPT_UI_AUDIT,
// additional OSD-specified UI port types (up to 16)
IPT_OSD_1,
IPT_OSD_2,
IPT_OSD_3,
IPT_OSD_4,
IPT_OSD_5,
IPT_OSD_6,
IPT_OSD_7,
IPT_OSD_8,
IPT_OSD_9,
IPT_OSD_10,
IPT_OSD_11,
IPT_OSD_12,
IPT_OSD_13,
IPT_OSD_14,
IPT_OSD_15,
IPT_OSD_16,
IPT_UI_LAST,
IPT_OTHER, // not mapped to standard defaults
IPT_SPECIAL, // uninterpreted characters
IPT_CUSTOM, // handled by custom code
IPT_OUTPUT,
IPT_COUNT,
// aliases for some types
IPT_PADDLE_H = IPT_PADDLE,
IPT_PEDAL1 = IPT_PEDAL,
IPT_POSITIONAL_H = IPT_POSITIONAL,
IPT_DIAL_H = IPT_DIAL
};
DECLARE_ENUM_INCDEC_OPERATORS(ioport_type)
// sequence types for input_port_seq() call
enum input_seq_type : int
{
SEQ_TYPE_INVALID = -1,
SEQ_TYPE_STANDARD = 0,
SEQ_TYPE_INCREMENT,
SEQ_TYPE_DECREMENT,
SEQ_TYPE_TOTAL
};
DECLARE_ENUM_INCDEC_OPERATORS(input_seq_type)
#endif // MAME_EMU_INPTTYPE_H

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,8 @@
#ifndef MAME_EMU_IOPORT_H
#define MAME_EMU_IOPORT_H
#include "inpttype.h"
#include "ioprocs.h"
#include <array>
@ -48,18 +50,6 @@ constexpr char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2;
constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
// sequence types for input_port_seq() call
enum input_seq_type : int
{
SEQ_TYPE_INVALID = -1,
SEQ_TYPE_STANDARD = 0,
SEQ_TYPE_INCREMENT,
SEQ_TYPE_DECREMENT,
SEQ_TYPE_TOTAL
};
DECLARE_ENUM_INCDEC_OPERATORS(input_seq_type)
// crosshair types
enum crosshair_axis_t
{
@ -89,323 +79,6 @@ enum ioport_group
};
// various input port types
enum ioport_type : u32
{
// pseudo-port types
IPT_INVALID = 0,
IPT_UNUSED,
IPT_END,
IPT_UNKNOWN,
IPT_PORT,
IPT_DIPSWITCH,
IPT_CONFIG,
// start buttons
IPT_START1,
IPT_START2,
IPT_START3,
IPT_START4,
IPT_START5,
IPT_START6,
IPT_START7,
IPT_START8,
IPT_START9,
IPT_START10,
// coin slots
IPT_COIN1,
IPT_COIN2,
IPT_COIN3,
IPT_COIN4,
IPT_COIN5,
IPT_COIN6,
IPT_COIN7,
IPT_COIN8,
IPT_COIN9,
IPT_COIN10,
IPT_COIN11,
IPT_COIN12,
IPT_BILL1,
// service coin
IPT_SERVICE1,
IPT_SERVICE2,
IPT_SERVICE3,
IPT_SERVICE4,
// tilt inputs
IPT_TILT1,
IPT_TILT2,
IPT_TILT3,
IPT_TILT4,
// misc other digital inputs
IPT_POWER_ON,
IPT_POWER_OFF,
IPT_SERVICE,
IPT_TILT,
IPT_INTERLOCK,
IPT_MEMORY_RESET,
IPT_VOLUME_UP,
IPT_VOLUME_DOWN,
IPT_START, // use the numbered start button(s) for coin-ops
IPT_SELECT,
IPT_KEYPAD,
IPT_KEYBOARD,
// digital joystick inputs
IPT_DIGITAL_JOYSTICK_FIRST,
// use IPT_JOYSTICK for panels where the player has one single joystick
IPT_JOYSTICK_UP,
IPT_JOYSTICK_DOWN,
IPT_JOYSTICK_LEFT,
IPT_JOYSTICK_RIGHT,
// use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels
IPT_JOYSTICKRIGHT_UP,
IPT_JOYSTICKRIGHT_DOWN,
IPT_JOYSTICKRIGHT_LEFT,
IPT_JOYSTICKRIGHT_RIGHT,
IPT_JOYSTICKLEFT_UP,
IPT_JOYSTICKLEFT_DOWN,
IPT_JOYSTICKLEFT_LEFT,
IPT_JOYSTICKLEFT_RIGHT,
IPT_DIGITAL_JOYSTICK_LAST,
// action buttons
IPT_BUTTON1,
IPT_BUTTON2,
IPT_BUTTON3,
IPT_BUTTON4,
IPT_BUTTON5,
IPT_BUTTON6,
IPT_BUTTON7,
IPT_BUTTON8,
IPT_BUTTON9,
IPT_BUTTON10,
IPT_BUTTON11,
IPT_BUTTON12,
IPT_BUTTON13,
IPT_BUTTON14,
IPT_BUTTON15,
IPT_BUTTON16,
// mahjong inputs
IPT_MAHJONG_FIRST,
IPT_MAHJONG_A,
IPT_MAHJONG_B,
IPT_MAHJONG_C,
IPT_MAHJONG_D,
IPT_MAHJONG_E,
IPT_MAHJONG_F,
IPT_MAHJONG_G,
IPT_MAHJONG_H,
IPT_MAHJONG_I,
IPT_MAHJONG_J,
IPT_MAHJONG_K,
IPT_MAHJONG_L,
IPT_MAHJONG_M,
IPT_MAHJONG_N,
IPT_MAHJONG_O,
IPT_MAHJONG_P,
IPT_MAHJONG_Q,
IPT_MAHJONG_KAN,
IPT_MAHJONG_PON,
IPT_MAHJONG_CHI,
IPT_MAHJONG_REACH,
IPT_MAHJONG_RON,
IPT_MAHJONG_FLIP_FLOP,
IPT_MAHJONG_BET,
IPT_MAHJONG_SCORE,
IPT_MAHJONG_DOUBLE_UP,
IPT_MAHJONG_BIG,
IPT_MAHJONG_SMALL,
IPT_MAHJONG_LAST_CHANCE,
IPT_MAHJONG_LAST,
// hanafuda inputs
IPT_HANAFUDA_FIRST,
IPT_HANAFUDA_A,
IPT_HANAFUDA_B,
IPT_HANAFUDA_C,
IPT_HANAFUDA_D,
IPT_HANAFUDA_E,
IPT_HANAFUDA_F,
IPT_HANAFUDA_G,
IPT_HANAFUDA_H,
IPT_HANAFUDA_YES,
IPT_HANAFUDA_NO,
IPT_HANAFUDA_LAST,
// gambling inputs
IPT_GAMBLING_FIRST,
IPT_GAMBLE_KEYIN, // attendant
IPT_GAMBLE_KEYOUT, // attendant
IPT_GAMBLE_SERVICE, // attendant
IPT_GAMBLE_BOOK, // attendant
IPT_GAMBLE_DOOR, // attendant
// IPT_GAMBLE_DOOR2, // many gambling games have several doors.
// IPT_GAMBLE_DOOR3,
// IPT_GAMBLE_DOOR4,
// IPT_GAMBLE_DOOR5,
IPT_GAMBLE_PAYOUT, // player
IPT_GAMBLE_BET, // player
IPT_GAMBLE_DEAL, // player
IPT_GAMBLE_STAND, // player
IPT_GAMBLE_TAKE, // player
IPT_GAMBLE_D_UP, // player
IPT_GAMBLE_HALF, // player
IPT_GAMBLE_HIGH, // player
IPT_GAMBLE_LOW, // player
// poker-specific inputs
IPT_POKER_HOLD1,
IPT_POKER_HOLD2,
IPT_POKER_HOLD3,
IPT_POKER_HOLD4,
IPT_POKER_HOLD5,
IPT_POKER_CANCEL,
// slot-specific inputs
IPT_SLOT_STOP1,
IPT_SLOT_STOP2,
IPT_SLOT_STOP3,
IPT_SLOT_STOP4,
IPT_SLOT_STOP_ALL,
IPT_GAMBLING_LAST,
// analog inputs
IPT_ANALOG_FIRST,
IPT_ANALOG_ABSOLUTE_FIRST,
IPT_AD_STICK_X, // absolute // autocenter
IPT_AD_STICK_Y, // absolute // autocenter
IPT_AD_STICK_Z, // absolute // autocenter
IPT_PADDLE, // absolute // autocenter
IPT_PADDLE_V, // absolute // autocenter
IPT_PEDAL, // absolute // autocenter
IPT_PEDAL2, // absolute // autocenter
IPT_PEDAL3, // absolute // autocenter
IPT_LIGHTGUN_X, // absolute
IPT_LIGHTGUN_Y, // absolute
IPT_POSITIONAL, // absolute // autocenter if not wraps
IPT_POSITIONAL_V, // absolute // autocenter if not wraps
IPT_ANALOG_ABSOLUTE_LAST,
IPT_DIAL, // relative
IPT_DIAL_V, // relative
IPT_TRACKBALL_X, // relative
IPT_TRACKBALL_Y, // relative
IPT_MOUSE_X, // relative
IPT_MOUSE_Y, // relative
IPT_ANALOG_LAST,
// analog adjuster support
IPT_ADJUSTER,
// the following are special codes for user interface handling - not to be used by drivers!
IPT_UI_FIRST,
IPT_UI_CONFIGURE,
IPT_UI_ON_SCREEN_DISPLAY,
IPT_UI_DEBUG_BREAK,
IPT_UI_PAUSE,
IPT_UI_PAUSE_SINGLE,
IPT_UI_REWIND_SINGLE,
IPT_UI_RESET_MACHINE,
IPT_UI_SOFT_RESET,
IPT_UI_SHOW_GFX,
IPT_UI_FRAMESKIP_DEC,
IPT_UI_FRAMESKIP_INC,
IPT_UI_THROTTLE,
IPT_UI_FAST_FORWARD,
IPT_UI_SHOW_FPS,
IPT_UI_SNAPSHOT,
IPT_UI_RECORD_MNG,
IPT_UI_RECORD_AVI,
IPT_UI_TOGGLE_CHEAT,
IPT_UI_UP,
IPT_UI_DOWN,
IPT_UI_LEFT,
IPT_UI_RIGHT,
IPT_UI_HOME,
IPT_UI_END,
IPT_UI_PAGE_UP,
IPT_UI_PAGE_DOWN,
IPT_UI_FOCUS_NEXT,
IPT_UI_FOCUS_PREV,
IPT_UI_SELECT,
IPT_UI_CANCEL,
IPT_UI_DISPLAY_COMMENT,
IPT_UI_CLEAR,
IPT_UI_ZOOM_IN,
IPT_UI_ZOOM_OUT,
IPT_UI_ZOOM_DEFAULT,
IPT_UI_PREV_GROUP,
IPT_UI_NEXT_GROUP,
IPT_UI_ROTATE,
IPT_UI_SHOW_PROFILER,
IPT_UI_TOGGLE_UI,
IPT_UI_RELEASE_POINTER,
IPT_UI_PASTE,
IPT_UI_SAVE_STATE,
IPT_UI_LOAD_STATE,
IPT_UI_TAPE_START,
IPT_UI_TAPE_STOP,
IPT_UI_DATS,
IPT_UI_FAVORITES,
IPT_UI_EXPORT,
IPT_UI_AUDIT,
// additional OSD-specified UI port types (up to 16)
IPT_OSD_1,
IPT_OSD_2,
IPT_OSD_3,
IPT_OSD_4,
IPT_OSD_5,
IPT_OSD_6,
IPT_OSD_7,
IPT_OSD_8,
IPT_OSD_9,
IPT_OSD_10,
IPT_OSD_11,
IPT_OSD_12,
IPT_OSD_13,
IPT_OSD_14,
IPT_OSD_15,
IPT_OSD_16,
IPT_UI_LAST,
IPT_OTHER, // not mapped to standard defaults
IPT_SPECIAL, // uninterpreted characters
IPT_CUSTOM, // handled by custom code
IPT_OUTPUT,
IPT_COUNT
};
DECLARE_ENUM_INCDEC_OPERATORS(ioport_type)
// aliases for some types
#define IPT_PADDLE_H IPT_PADDLE
#define IPT_PEDAL1 IPT_PEDAL
#define IPT_POSITIONAL_H IPT_POSITIONAL
#define IPT_DIAL_H IPT_DIAL
// input type classes
enum ioport_type_class
{

View File

@ -512,16 +512,18 @@ void lua_engine::initialize_input(sol::table &emu)
auto uiinput_type = sol().registry().new_usertype<ui_input_manager>("uiinput", sol::no_constructor);
uiinput_type["find_mouse"] =
uiinput_type.set_function("reset", &ui_input_manager::reset);
uiinput_type.set_function(
"find_mouse",
[] (ui_input_manager &ui)
{
int32_t x, y;
bool button;
render_target *rt = ui.find_mouse(&x, &y, &button);
return std::make_tuple(x, y, button, rt);
};
uiinput_type["pressed"] = &ui_input_manager::pressed;
uiinput_type["pressed_repeat"] = &ui_input_manager::pressed_repeat;
});
uiinput_type.set_function("pressed", &ui_input_manager::pressed);
uiinput_type.set_function("pressed_repeat", &ui_input_manager::pressed_repeat);
uiinput_type["presses_enabled"] = sol::property(&ui_input_manager::presses_enabled, &ui_input_manager::set_presses_enabled);
}

View File

@ -11,6 +11,8 @@
#include "emu.h"
#include "ui/analogipt.h"
#include "ui/textbox.h"
#include <algorithm>
#include <iterator>
#include <string>
@ -19,6 +21,20 @@
namespace ui {
namespace {
char const HELP_TEXT[] = N_p("menu-analoginput",
"Show/hide settings \t\t%1$s\n"
"Decrease value \t\t%2$s\n"
"Increase value \t\t%3$s\n"
"Restore default value \t\t%4$s\n"
"Previous device \t\t%5$s\n"
"Next device \t\t%6$s\n"
"Return to previous menu \t\t%7$s");
} // anonymous namespace
inline menu_analog::item_data::item_data(ioport_field &f, int t) noexcept
: field(f)
, type(t)
@ -63,7 +79,7 @@ menu_analog::menu_analog(mame_ui_manager &mui, render_container &container)
, m_hide_menu(false)
{
set_process_flags(PROCESS_LR_REPEAT);
set_heading(_("Analog Input Adjustments"));
set_heading(_("menu-analoginput", "Analog Input Adjustments"));
}
@ -102,7 +118,7 @@ void menu_analog::custom_render(void *selectedref, float top, float bottom, floa
if (m_hide_menu)
{
if (m_prompt.empty())
m_prompt = util::string_format(_("Press %s to show menu"), ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY));
m_prompt = util::string_format(_("menu-analoginput", "Press %s to show settings"), ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY));
draw_text_box(
&m_prompt, &m_prompt + 1,
boxleft, boxright, y - top, y - top + line_height() + (tb_border() * 2.0f),
@ -221,6 +237,22 @@ void menu_analog::handle(event const *ev)
m_hide_menu = !m_hide_menu;
set_process_flags(PROCESS_LR_REPEAT | (m_hide_menu ? (PROCESS_CUSTOM_NAV | PROCESS_CUSTOM_ONLY) : 0));
}
else if (IPT_UI_HELP == ev->iptkey)
{
stack_push<menu_fixed_textbox>(
ui(),
container(),
_("menu-analoginput", "Analog Input Adjustments Help"),
util::string_format(
_(HELP_TEXT),
ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY),
ui().get_general_input_setting(IPT_UI_LEFT),
ui().get_general_input_setting(IPT_UI_RIGHT),
ui().get_general_input_setting(IPT_UI_CLEAR),
ui().get_general_input_setting(IPT_UI_PREV_GROUP),
ui().get_general_input_setting(IPT_UI_NEXT_GROUP),
ui().get_general_input_setting(IPT_UI_BACK)));
}
else if (m_hide_menu)
{
switch (ev->iptkey)
@ -386,22 +418,22 @@ void menu_analog::populate()
{
default:
case ANALOG_ITEM_KEYSPEED:
text = string_format(_("%1$s Increment/Decrement Speed"), field->name());
text = string_format(_("menu-analoginput", "%1$s Increment/Decrement Speed"), field->name());
data.cur = settings.delta;
break;
case ANALOG_ITEM_CENTERSPEED:
text = string_format(_("%1$s Auto-centering Speed"), field->name());
text = string_format(_("menu-analoginput", "%1$s Auto-centering Speed"), field->name());
data.cur = settings.centerdelta;
break;
case ANALOG_ITEM_REVERSE:
text = string_format(_("%1$s Reverse"), field->name());
text = string_format(_("menu-analoginput", "%1$s Reverse"), field->name());
data.cur = settings.reverse;
break;
case ANALOG_ITEM_SENSITIVITY:
text = string_format(_("%1$s Sensitivity"), field->name());
text = string_format(_("menu-analoginput", "%1$s Sensitivity"), field->name());
data.cur = settings.sensitivity;
break;
}
@ -416,7 +448,7 @@ void menu_analog::populate()
// display a message if there are toggle inputs enabled
if (!prev_owner)
item_append(_("[no analog inputs are enabled]"), FLAG_DISABLE, nullptr);
item_append(_("menu-analoginput", "[no analog inputs are enabled]"), FLAG_DISABLE, nullptr);
item_append(menu_item_type::SEPARATOR);

View File

@ -127,7 +127,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
util::string_format(
_("Cancel audit?\n\nPress %1$s to cancel\nPress %2$s to continue"),
ui().get_general_input_setting(IPT_UI_SELECT),
ui().get_general_input_setting(IPT_UI_CANCEL)),
ui().get_general_input_setting(IPT_UI_BACK)),
text_layout::text_justify::CENTER,
0.5F, 0.5F,
UI_RED_COLOR);
@ -136,7 +136,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
}
bool menu_audit::custom_ui_cancel()
bool menu_audit::custom_ui_back()
{
return m_phase != phase::CONFIRMATION;
}
@ -162,7 +162,7 @@ void menu_audit::handle(event const *ev)
set_process_flags(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT);
m_phase = phase::AUDIT;
m_fast = ITEMREF_START_FAST == ev->itemref;
m_prompt = util::string_format(_("Press %1$s to cancel\n"), ui().get_general_input_setting(IPT_UI_CANCEL));
m_prompt = util::string_format(_("Press %1$s to cancel\n"), ui().get_general_input_setting(IPT_UI_BACK));
m_future.resize(std::thread::hardware_concurrency());
for (auto &future : m_future)
future = std::async(std::launch::async, [this] () { return do_audit(); });
@ -185,7 +185,7 @@ void menu_audit::handle(event const *ev)
}
stack_pop();
}
else if (machine().ui_input().pressed(IPT_UI_CANCEL))
else if (machine().ui_input().pressed(IPT_UI_BACK))
{
if (phase::AUDIT == m_phase)
m_phase = phase::CANCELLATION;

View File

@ -31,7 +31,7 @@ public:
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override;
virtual bool custom_ui_back() override;
private:
enum class phase { CONFIRMATION, AUDIT, CANCELLATION };

View File

@ -190,17 +190,6 @@ void menu_confswitch::handle(event const *ev)
switch (ev->iptkey)
{
// if selected, reset to default value
case IPT_UI_SELECT:
{
ioport_field::user_settings settings;
field.get_user_settings(settings);
settings.value = field.defvalue();
field.set_user_settings(settings);
}
changed = true;
break;
// left goes to previous setting
case IPT_UI_LEFT:
field.select_previous_setting();
@ -208,11 +197,26 @@ void menu_confswitch::handle(event const *ev)
break;
// right goes to next setting
case IPT_UI_SELECT:
case IPT_UI_RIGHT:
field.select_next_setting();
changed = true;
break;
// if cleared, reset to default value
case IPT_UI_CLEAR:
{
ioport_field::user_settings settings;
field.get_user_settings(settings);
if (field.defvalue() != settings.value)
{
settings.value = field.defvalue();
field.set_user_settings(settings);
changed = true;
}
}
break;
// trick to get previous group - depend on headings having null reference
case IPT_UI_PREV_GROUP:
{

View File

@ -168,7 +168,7 @@ protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
virtual bool custom_ui_back() override { return !m_search.empty(); }
private:
virtual void populate() override;

View File

@ -117,7 +117,7 @@ menu_file_create::menu_file_create(mame_ui_manager &mui, render_container &conta
, m_current_format(nullptr)
{
m_image = image;
m_ok = true;
m_ok = false;
m_filename.reserve(1024);
m_filename = core_filename_extract_base(current_file);
@ -157,6 +157,16 @@ void menu_file_create::custom_render(void *selectedref, float top, float bottom,
}
//-------------------------------------------------
// custom_ui_back - override back handling
//-------------------------------------------------
bool menu_file_create::custom_ui_back()
{
return (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty();
}
//-------------------------------------------------
// populate - populates the file creator menu
//-------------------------------------------------
@ -164,7 +174,6 @@ void menu_file_create::custom_render(void *selectedref, float top, float bottom,
void menu_file_create::populate()
{
std::string buffer;
const image_device_format *format;
const std::string *new_image_name;
// append the "New Image Name" item
@ -180,9 +189,10 @@ void menu_file_create::populate()
item_append(_("New Image Name:"), *new_image_name, 0, ITEMREF_NEW_IMAGE_NAME);
// do we support multiple formats?
if (ENABLE_FORMATS) format = m_image->formatlist().front().get();
if (ENABLE_FORMATS && (format != nullptr))
image_device_format const *const format = ENABLE_FORMATS ? m_image->formatlist().front().get() : nullptr;
if (format)
{
// FIXME: is this in the right order? It reassigns m_current_format after reading it.
item_append(_("Image Format:"), m_current_format->description(), 0, ITEMREF_FORMAT);
m_current_format = format;
}
@ -212,31 +222,38 @@ void menu_file_create::handle(event const *ev)
if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1)
{
m_current_file = m_filename;
m_ok = true;
stack_pop();
}
else
{
ui().popup_time(1, "%s", _("Please enter a file extension too"));
}
}
break;
case IPT_UI_PASTE:
if (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME)
if (ev->itemref == ITEMREF_NEW_IMAGE_NAME)
{
if (paste_text(m_filename, &osd_is_valid_filename_char))
reset(reset_options::REMEMBER_POSITION);
ev->item->set_subtext(m_filename + "_");
}
break;
case IPT_SPECIAL:
if (get_selection_ref() == ITEMREF_NEW_IMAGE_NAME)
if (ev->itemref == ITEMREF_NEW_IMAGE_NAME)
{
if (input_character(m_filename, ev->unichar, &osd_is_valid_filename_char))
reset(reset_options::REMEMBER_POSITION);
ev->item->set_subtext(m_filename + "_");
}
break;
case IPT_UI_CANCEL:
m_ok = false;
if ((ev->itemref == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty())
{
m_filename.clear();
ev->item->set_subtext("_");
}
break;
}
}

View File

@ -49,6 +49,7 @@ public:
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_back() override;
private:
virtual void populate() override;

View File

@ -46,7 +46,7 @@ public:
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_filename.empty(); }
virtual bool custom_ui_back() override { return !m_filename.empty(); }
virtual bool custom_mouse_down() override;
private:

View File

@ -394,22 +394,12 @@ void menu_input::handle(event const *ev)
if (machine().ui_input().pressed(IPT_UI_CANCEL))
{
// if UI_CANCEL is pressed, abort
// if UI_CANCEL is pressed, abort and abandon changes
pollingitem = nullptr;
set_process_flags(PROCESS_LR_ALWAYS);
if (!seq_poll->modified() || modified_ticks == osd_ticks())
{
// cancelled immediately - toggle between default and none
record_next = false;
toggle_none_default(item->seq, starting_seq, *item->defseq);
seqchangeditem = item;
}
else
{
// entered something before cancelling - abandon change
invalidate = true;
}
invalidate = true;
seq_poll.reset();
machine().ui_input().reset();
}
else if (seq_poll->poll()) // poll again; if finished, update the sequence
{
@ -429,6 +419,7 @@ void menu_input::handle(event const *ev)
erroritem = item;
}
seq_poll.reset();
machine().ui_input().reset();
}
}
else if (ev && ev->itemref)

View File

@ -950,7 +950,7 @@ void menu::handle_events(uint32_t flags, event &ev)
ev.iptkey = IPT_UI_SELECT;
if (is_last_selected() && m_needs_prev_menu_item)
{
ev.iptkey = IPT_UI_CANCEL;
ev.iptkey = IPT_UI_BACK;
stack_pop();
if (is_special_main_menu())
machine().schedule_exit();
@ -1029,7 +1029,7 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
{
if (is_last_selected() && m_needs_prev_menu_item)
{
iptkey = IPT_UI_CANCEL;
iptkey = IPT_UI_BACK;
stack_pop();
if (is_special_main_menu())
machine().schedule_exit();
@ -1038,7 +1038,7 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
}
// UI configure hides the menus
if (!(flags & PROCESS_NOKEYS) && exclusive_input_pressed(iptkey, IPT_UI_CONFIGURE, 0) && !m_global_state.stack_has_special_main_menu())
if (!(flags & PROCESS_NOKEYS) && exclusive_input_pressed(iptkey, IPT_UI_MENU, 0) && !m_global_state.stack_has_special_main_menu())
{
if (is_one_shot())
stack_pop();
@ -1051,10 +1051,10 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
if (flags & PROCESS_ONLYCHAR)
return;
// hitting cancel also pops the stack
if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0))
// hitting back also pops the stack
if (exclusive_input_pressed(iptkey, IPT_UI_BACK, 0))
{
if (!custom_ui_cancel())
if (!custom_ui_back())
{
stack_pop();
if (is_special_main_menu())

View File

@ -350,7 +350,7 @@ protected:
void set_process_flags(uint32_t flags) { m_process_flags = flags; }
virtual void handle_events(uint32_t flags, event &ev);
virtual void handle_keys(uint32_t flags, int &iptkey);
virtual bool custom_ui_cancel() { return false; }
virtual bool custom_ui_back() { return false; }
virtual bool custom_mouse_down() { return false; }
virtual bool custom_mouse_scroll(int lines) { return false; }

View File

@ -103,6 +103,9 @@ void menu_plugin_opt::handle(event const *ev)
case IPT_UI_CLEAR:
key = "clear";
break;
case IPT_UI_BACK:
key = "back";
break;
case IPT_UI_CANCEL:
key = "cancel";
break;
@ -120,7 +123,7 @@ void menu_plugin_opt::handle(event const *ev)
set_selection(reinterpret_cast<void *>(uintptr_t(*result.second)));
if (result.first)
reset(reset_options::REMEMBER_REF);
else if (ev && (ev->iptkey == IPT_UI_CANCEL))
else if (ev && (ev->iptkey == IPT_UI_BACK))
stack_pop();
}
}

View File

@ -45,7 +45,7 @@ public:
virtual ~menu_plugin_opt();
protected:
virtual bool custom_ui_cancel() override { return true; }
virtual bool custom_ui_back() override { return true; }
private:
virtual void populate() override;

View File

@ -38,7 +38,7 @@ void menu_confirm_quit::custom_render(void *selectedref, float top, float bottom
"Press %1$s to quit\n"
"Press %2$s to return to emulation"),
ui().get_general_input_setting(IPT_UI_SELECT),
ui().get_general_input_setting(IPT_UI_CANCEL)),
ui().get_general_input_setting(IPT_UI_BACK)),
text_layout::text_justify::CENTER,
0.5f, 0.5f,
UI_RED_COLOR);
@ -54,7 +54,7 @@ void menu_confirm_quit::handle(event const *ev)
{
if (machine().ui_input().pressed(IPT_UI_SELECT))
machine().schedule_exit();
else if (machine().ui_input().pressed(IPT_UI_CANCEL))
else if (machine().ui_input().pressed(IPT_UI_BACK))
stack_pop();
}

View File

@ -40,7 +40,7 @@ public:
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
virtual bool custom_ui_back() override { return !m_search.empty(); }
private:
enum { VISIBLE_SEARCH_ITEMS = 200 };

View File

@ -1450,24 +1450,34 @@ void menu_select_launch::handle_keys(u32 flags, int &iptkey)
return;
}
if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0))
if (exclusive_input_pressed(iptkey, IPT_UI_BACK, 0))
{
if (m_ui_error)
{
// dismiss error
return;
}
else if (!m_search.empty())
else if (!is_special_main_menu() && m_search.empty())
{
// pop the stack if this isn't the root session menu
stack_pop();
return;
}
}
if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0))
{
if (!m_search.empty())
{
// escape pressed with non-empty search text clears it
m_search.clear();
reset(reset_options::REMEMBER_REF);
}
else
else if (is_special_main_menu())
{
// otherwise pop the stack
// this is the root session menu, exit
stack_pop();
if (is_special_main_menu())
machine().schedule_exit();
machine().schedule_exit();
}
return;
}
@ -1779,7 +1789,7 @@ void menu_select_launch::handle_events(u32 flags, event &ev)
}
else if (hover() == HOVER_BACKTRACK)
{
ev.iptkey = IPT_UI_CANCEL;
ev.iptkey = IPT_UI_BACK;
stack_pop();
if (is_special_main_menu())
machine().schedule_exit();

View File

@ -124,7 +124,7 @@ void simple_menu_select_game::handle(event const *ev)
else
{
// handle selections
switch(ev->iptkey)
switch (ev->iptkey)
{
case IPT_UI_SELECT:
inkey_select(*ev);

View File

@ -31,7 +31,7 @@ public:
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
virtual bool custom_ui_back() override { return !m_search.empty(); }
private:
enum { VISIBLE_GAMES_IN_LIST = 15 };

View File

@ -99,7 +99,6 @@ void menu_sliders::handle(event const *ev)
break;
// restore default
case IPT_UI_SELECT:
case IPT_UI_CLEAR:
increment = slider->defval - curvalue;
break;

View File

@ -262,7 +262,7 @@ void menu_load_save_state_base::handle(event const *ev)
_("Delete saved state %1$s?\nPress %2$s to delete\nPress %3$s to cancel"),
m_confirm_delete->visible_name(),
ui().get_general_input_setting(IPT_UI_SELECT),
ui().get_general_input_setting(IPT_UI_CANCEL));
ui().get_general_input_setting(IPT_UI_BACK));
}
}
else if (!m_confirm_delete)
@ -396,7 +396,7 @@ void menu_load_save_state_base::handle_keys(uint32_t flags, int &iptkey)
m_keys_released = false;
reset(reset_options::REMEMBER_POSITION);
}
else if (exclusive_input_pressed(iptkey, IPT_UI_CANCEL, 0))
else if (exclusive_input_pressed(iptkey, IPT_UI_BACK, 0))
{
// don't delete it - dismiss the prompt
m_switch_poller.reset();

View File

@ -65,7 +65,7 @@ public:
virtual ~menu_software_list() override;
protected:
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
virtual bool custom_ui_back() override { return !m_search.empty(); }
private:
struct entry_info

View File

@ -441,7 +441,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
machine().schedule_exit();
return UI_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;
@ -1301,7 +1301,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;

View File

@ -527,7 +527,7 @@ private:
}
// cancel or graphics viewer dismisses the viewer
if (input.pressed(IPT_UI_CANCEL) || input.pressed(IPT_UI_SHOW_GFX))
if (input.pressed(IPT_UI_BACK) || input.pressed(IPT_UI_SHOW_GFX))
return cancel(uistate);
return uistate;

View File

@ -0,0 +1,592 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
//============================================================
//
// assignmenthelper.cpp - input assignment setup helper
//
//============================================================
#include "assignmenthelper.h"
#include "interface/inputseq.h"
#include "inpttype.h"
namespace osd {
bool joystick_assignment_helper::add_assignment(
input_device::assignment_vector &assignments,
ioport_type fieldtype,
input_seq_type seqtype,
input_item_class itemclass,
input_item_modifier modifier,
std::initializer_list<input_item_id> items)
{
for (input_item_id item : items)
{
if (ITEM_ID_INVALID != item)
{
assignments.emplace_back(
fieldtype,
seqtype,
input_seq(input_code(DEVICE_CLASS_JOYSTICK, 0, itemclass, modifier, item)));
return true;
}
}
return false;
}
bool joystick_assignment_helper::add_button_assignment(
input_device::assignment_vector &assignments,
ioport_type field_type,
std::initializer_list<input_item_id> items)
{
return add_assignment(
assignments,
field_type,
SEQ_TYPE_STANDARD,
ITEM_CLASS_SWITCH,
ITEM_MODIFIER_NONE,
items);
}
bool joystick_assignment_helper::add_button_pair_assignment(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id button1,
input_item_id button2)
{
if ((ITEM_ID_INVALID == button1) || (ITEM_ID_INVALID == button2))
return false;
assignments.emplace_back(
field1,
SEQ_TYPE_STANDARD,
make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button1));
assignments.emplace_back(
field2,
SEQ_TYPE_STANDARD,
make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button2));
return true;
}
bool joystick_assignment_helper::add_axis_inc_dec_assignment(
input_device::assignment_vector &assignments,
ioport_type field_type,
input_item_id button_dec,
input_item_id button_inc)
{
if ((ITEM_ID_INVALID == button_dec) || (ITEM_ID_INVALID == button_inc))
return false;
assignments.emplace_back(
field_type,
SEQ_TYPE_DECREMENT,
make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button_dec));
assignments.emplace_back(
field_type,
SEQ_TYPE_INCREMENT,
make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, button_inc));
return true;
}
bool joystick_assignment_helper::add_axis_pair_assignment(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id axis)
{
if (ITEM_ID_INVALID == axis)
return false;
assignments.emplace_back(
field1,
SEQ_TYPE_STANDARD,
make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_XAXIS == axis) ? ITEM_MODIFIER_LEFT : (ITEM_ID_YAXIS == axis) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG,
axis));
assignments.emplace_back(
field2,
SEQ_TYPE_STANDARD,
make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_XAXIS == axis) ? ITEM_MODIFIER_RIGHT : (ITEM_ID_YAXIS == axis) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS,
axis));
return true;
}
bool joystick_assignment_helper::consume_button_pair(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id &button1,
input_item_id &button2)
{
if (!add_button_pair_assignment(assignments, field1, field2, button1, button2))
return false;
button1 = ITEM_ID_INVALID;
button2 = ITEM_ID_INVALID;
return true;
}
bool joystick_assignment_helper::consume_trigger_pair(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id &axis1,
input_item_id &axis2)
{
if ((ITEM_ID_INVALID == axis1) || (ITEM_ID_INVALID == axis2))
return false;
assignments.emplace_back(
field1,
SEQ_TYPE_STANDARD,
make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axis1));
assignments.emplace_back(
field2,
SEQ_TYPE_STANDARD,
make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, axis2));
axis1 = ITEM_ID_INVALID;
axis2 = ITEM_ID_INVALID;
return true;
}
bool joystick_assignment_helper::consume_axis_pair(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id &axis)
{
if (!add_axis_pair_assignment(assignments, field1, field2, axis))
return false;
axis = ITEM_ID_INVALID;
return true;
}
void joystick_assignment_helper::add_directional_assignments(
input_device::assignment_vector &assignments,
input_item_id xaxis,
input_item_id yaxis,
input_item_id leftswitch,
input_item_id rightswitch,
input_item_id upswitch,
input_item_id downswitch)
{
// see if we have complementary pairs of directional switches
bool const hswitches = (ITEM_ID_INVALID != leftswitch) && (ITEM_ID_INVALID != rightswitch);
bool const vswitches = (ITEM_ID_INVALID != upswitch) && (ITEM_ID_INVALID != downswitch);
// use X axis if present
if (ITEM_ID_INVALID != xaxis)
{
// use this for horizontal axis movement
input_seq const xseq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, xaxis));
assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_STANDARD, xseq);
assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_STANDARD, xseq);
assignments.emplace_back(IPT_DIAL, SEQ_TYPE_STANDARD, xseq);
assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_STANDARD, xseq);
assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_STANDARD, xseq);
assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_STANDARD, xseq);
// use it for the main left/right control, too
input_seq leftseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_XAXIS == xaxis) ? ITEM_MODIFIER_LEFT : ITEM_MODIFIER_NEG, xaxis));
input_seq rightseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_XAXIS == xaxis) ? ITEM_MODIFIER_RIGHT : ITEM_MODIFIER_POS, xaxis));
if (ITEM_ID_INVALID != leftswitch)
{
leftseq += input_seq::or_code;
leftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftswitch);
}
if (ITEM_ID_INVALID != rightswitch)
{
rightseq += input_seq::or_code;
rightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightswitch);
}
assignments.emplace_back(IPT_JOYSTICK_LEFT, SEQ_TYPE_STANDARD, leftseq);
assignments.emplace_back(IPT_JOYSTICK_RIGHT, SEQ_TYPE_STANDARD, rightseq);
// use for vertical navigation if there's no Y axis, or horizontal otherwise
if (ITEM_ID_INVALID != yaxis)
{
// if left/right are both present but not both up/down, they'll be taken for vertical navigation
if (hswitches && !vswitches)
{
leftseq.backspace();
if (ITEM_ID_INVALID != upswitch)
leftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch);
else
leftseq.backspace();
rightseq.backspace();
if (ITEM_ID_INVALID != downswitch)
rightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch);
else
rightseq.backspace();
}
assignments.emplace_back(IPT_UI_LEFT, SEQ_TYPE_STANDARD, leftseq);
assignments.emplace_back(IPT_UI_RIGHT, SEQ_TYPE_STANDARD, rightseq);
}
else
{
// prefer D-pad up/down for vertical navigation if present
if (!hswitches || vswitches)
{
while (leftseq.length() > 1)
leftseq.backspace();
if (ITEM_ID_INVALID != upswitch)
{
leftseq += input_seq::or_code;
leftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch);
}
while (rightseq.length() > 1)
rightseq.backspace();
if (ITEM_ID_INVALID != downswitch)
{
rightseq += input_seq::or_code;
rightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch);
}
}
assignments.emplace_back(IPT_UI_UP, SEQ_TYPE_STANDARD, leftseq);
assignments.emplace_back(IPT_UI_DOWN, SEQ_TYPE_STANDARD, rightseq);
}
}
else
{
// without a primary analog X axis, we still want D-pad left/right controls if possible
add_button_assignment(assignments, IPT_JOYSTICK_LEFT, { leftswitch });
add_button_assignment(assignments, IPT_JOYSTICK_RIGHT, { rightswitch });
// vertical navigation gets first pick on directional controls
add_button_assignment(assignments, IPT_UI_LEFT, { (hswitches && !vswitches) ? upswitch : leftswitch });
add_button_assignment(assignments, IPT_UI_RIGHT, { (hswitches && !vswitches) ? downswitch : rightswitch });
}
// use Y axis if present
if (ITEM_ID_INVALID != yaxis)
{
// use this for vertical axis movement
input_seq const yseq(make_code(ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, yaxis));
assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_STANDARD, yseq);
assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_STANDARD, yseq);
assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_STANDARD, yseq);
assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_STANDARD, yseq);
assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_STANDARD, yseq);
assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_STANDARD, yseq);
// use it for the main up/down control, too
input_seq upseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_YAXIS == yaxis) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG, yaxis));
input_seq downseq(make_code(ITEM_CLASS_SWITCH, (ITEM_ID_YAXIS == yaxis) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS, yaxis));
if (ITEM_ID_INVALID != upswitch)
{
upseq += input_seq::or_code;
upseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch);
}
if (ITEM_ID_INVALID != downswitch)
{
downseq += input_seq::or_code;
downseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch);
}
assignments.emplace_back(IPT_JOYSTICK_UP, SEQ_TYPE_STANDARD, upseq);
assignments.emplace_back(IPT_JOYSTICK_DOWN, SEQ_TYPE_STANDARD, downseq);
// if available, this is used for vertical navigation
if (hswitches && !vswitches)
{
if (upseq.length() > 1)
upseq.backspace();
else
upseq += input_seq::or_code;
upseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftswitch);
if (downseq.length() > 1)
downseq.backspace();
else
downseq += input_seq::or_code;
downseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightswitch);
}
assignments.emplace_back(IPT_UI_UP, SEQ_TYPE_STANDARD, upseq);
assignments.emplace_back(IPT_UI_DOWN, SEQ_TYPE_STANDARD, downseq);
}
else
{
// without a primary analog Y axis, we still want D-pad up/down controls if possible
add_button_assignment(assignments, IPT_JOYSTICK_UP, { upswitch });
add_button_assignment(assignments, IPT_JOYSTICK_DOWN, { downswitch });
// vertical navigation may be assigned to X axis if Y axis is not present
bool const dpadflip = (ITEM_ID_INVALID != xaxis) == (!hswitches || vswitches);
add_button_assignment(
assignments,
(ITEM_ID_INVALID != xaxis) ? IPT_UI_LEFT : IPT_UI_UP,
{ dpadflip ? leftswitch : upswitch });
add_button_assignment(
assignments,
(ITEM_ID_INVALID != xaxis) ? IPT_UI_RIGHT : IPT_UI_DOWN,
{ dpadflip ? rightswitch : downswitch });
}
// if we're missing either primary axis, fall back to D-pad for analog increment/decrement
if ((ITEM_ID_INVALID == xaxis) || (ITEM_ID_INVALID == yaxis))
{
if (ITEM_ID_INVALID != leftswitch)
{
input_seq const leftseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftswitch));
assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_DECREMENT, leftseq);
assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_DECREMENT, leftseq);
assignments.emplace_back(IPT_DIAL, SEQ_TYPE_DECREMENT, leftseq);
assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_DECREMENT, leftseq);
assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_DECREMENT, leftseq);
assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_DECREMENT, leftseq);
}
if (ITEM_ID_INVALID != rightswitch)
{
input_seq const rightseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightswitch));
assignments.emplace_back(IPT_PADDLE, SEQ_TYPE_INCREMENT, rightseq);
assignments.emplace_back(IPT_POSITIONAL, SEQ_TYPE_INCREMENT, rightseq);
assignments.emplace_back(IPT_DIAL, SEQ_TYPE_INCREMENT, rightseq);
assignments.emplace_back(IPT_TRACKBALL_X, SEQ_TYPE_INCREMENT, rightseq);
assignments.emplace_back(IPT_AD_STICK_X, SEQ_TYPE_INCREMENT, rightseq);
assignments.emplace_back(IPT_LIGHTGUN_X, SEQ_TYPE_INCREMENT, rightseq);
}
if (ITEM_ID_INVALID != upswitch)
{
input_seq const upseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, upswitch));
assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_DECREMENT, upseq);
assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_DECREMENT, upseq);
assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_DECREMENT, upseq);
assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_DECREMENT, upseq);
assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_DECREMENT, upseq);
assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_DECREMENT, upseq);
}
if (ITEM_ID_INVALID != downswitch)
{
input_seq const downseq(make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, downswitch));
assignments.emplace_back(IPT_PADDLE_V, SEQ_TYPE_INCREMENT, downseq);
assignments.emplace_back(IPT_POSITIONAL_V, SEQ_TYPE_INCREMENT, downseq);
assignments.emplace_back(IPT_DIAL_V, SEQ_TYPE_INCREMENT, downseq);
assignments.emplace_back(IPT_TRACKBALL_Y, SEQ_TYPE_INCREMENT, downseq);
assignments.emplace_back(IPT_AD_STICK_Y, SEQ_TYPE_INCREMENT, downseq);
assignments.emplace_back(IPT_LIGHTGUN_Y, SEQ_TYPE_INCREMENT, downseq);
}
}
}
void joystick_assignment_helper::add_twin_stick_assignments(
input_device::assignment_vector &assignments,
input_item_id leftx,
input_item_id lefty,
input_item_id rightx,
input_item_id righty,
input_item_id leftleft,
input_item_id leftright,
input_item_id leftup,
input_item_id leftdown,
input_item_id rightleft,
input_item_id rightright,
input_item_id rightup,
input_item_id rightdown)
{
// we'll add these at the end if they aren't empty
input_seq leftleftseq, leftrightseq, leftupseq, leftdownseq;
input_seq rightleftseq, rightrightseq, rightupseq, rightdownseq;
// only use axes if there are at least two axes in the same orientation
bool const useaxes =
((ITEM_ID_INVALID != leftx) && (ITEM_ID_INVALID != rightx)) ||
((ITEM_ID_INVALID != lefty) && (ITEM_ID_INVALID != righty));
if (useaxes)
{
// left stick
if (ITEM_ID_INVALID != leftx)
{
leftleftseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_XAXIS == leftx) ? ITEM_MODIFIER_LEFT : ITEM_MODIFIER_NEG,
leftx);
leftrightseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_XAXIS == leftx) ? ITEM_MODIFIER_RIGHT : ITEM_MODIFIER_POS,
leftx);
}
if (ITEM_ID_INVALID != lefty)
{
leftupseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_YAXIS == lefty) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG,
lefty);
leftdownseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_YAXIS == lefty) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS,
lefty);
}
// right stick
if (ITEM_ID_INVALID != rightx)
{
rightleftseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_XAXIS == rightx) ? ITEM_MODIFIER_LEFT : ITEM_MODIFIER_NEG,
rightx);
rightrightseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_XAXIS == rightx) ? ITEM_MODIFIER_RIGHT : ITEM_MODIFIER_POS,
rightx);
}
if (ITEM_ID_INVALID != righty)
{
rightupseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_YAXIS == righty) ? ITEM_MODIFIER_UP : ITEM_MODIFIER_NEG,
righty);
rightdownseq += make_code(
ITEM_CLASS_SWITCH,
(ITEM_ID_YAXIS == righty) ? ITEM_MODIFIER_DOWN : ITEM_MODIFIER_POS,
righty);
}
}
// only use switches if we have at least one pair of matching opposing directions
bool const lefth = (ITEM_ID_INVALID != leftleft) && (ITEM_ID_INVALID != leftright);
bool const leftv = (ITEM_ID_INVALID != leftup) && (ITEM_ID_INVALID != leftdown);
bool const righth = (ITEM_ID_INVALID != rightleft) && (ITEM_ID_INVALID != rightright);
bool const rightv = (ITEM_ID_INVALID != rightup) && (ITEM_ID_INVALID != rightdown);
if ((lefth && righth) || (leftv && rightv))
{
// left stick
if (ITEM_ID_INVALID != leftleft)
{
if (!leftleftseq.empty())
leftleftseq += input_seq::or_code;
leftleftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftleft);
}
if (ITEM_ID_INVALID != leftright)
{
if (!leftrightseq.empty())
leftrightseq += input_seq::or_code;
leftrightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftright);
}
if (ITEM_ID_INVALID != leftup)
{
if (!leftupseq.empty())
leftupseq += input_seq::or_code;
leftupseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftup);
}
if (ITEM_ID_INVALID != leftdown)
{
if (!leftdownseq.empty())
leftdownseq += input_seq::or_code;
leftdownseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, leftdown);
}
// right stick
if (ITEM_ID_INVALID != rightleft)
{
if (!rightleftseq.empty())
rightleftseq += input_seq::or_code;
rightleftseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightleft);
}
if (ITEM_ID_INVALID != rightright)
{
if (!rightrightseq.empty())
rightrightseq += input_seq::or_code;
rightrightseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightright);
}
if (ITEM_ID_INVALID != rightup)
{
if (!rightupseq.empty())
rightupseq += input_seq::or_code;
rightupseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightup);
}
if (ITEM_ID_INVALID != rightdown)
{
if (!rightdownseq.empty())
rightdownseq += input_seq::or_code;
rightdownseq += make_code(ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, rightdown);
}
}
// now add collected assignments
if (!leftleftseq.empty())
assignments.emplace_back(IPT_JOYSTICKLEFT_LEFT, SEQ_TYPE_STANDARD, leftleftseq);
if (!leftrightseq.empty())
assignments.emplace_back(IPT_JOYSTICKLEFT_RIGHT, SEQ_TYPE_STANDARD, leftrightseq);
if (!leftupseq.empty())
assignments.emplace_back(IPT_JOYSTICKLEFT_UP, SEQ_TYPE_STANDARD, leftupseq);
if (!leftdownseq.empty())
assignments.emplace_back(IPT_JOYSTICKLEFT_DOWN, SEQ_TYPE_STANDARD, leftdownseq);
if (!rightleftseq.empty())
assignments.emplace_back(IPT_JOYSTICKRIGHT_LEFT, SEQ_TYPE_STANDARD, rightleftseq);
if (!rightrightseq.empty())
assignments.emplace_back(IPT_JOYSTICKRIGHT_RIGHT, SEQ_TYPE_STANDARD, rightrightseq);
if (!rightupseq.empty())
assignments.emplace_back(IPT_JOYSTICKRIGHT_UP, SEQ_TYPE_STANDARD, rightupseq);
if (!rightdownseq.empty())
assignments.emplace_back(IPT_JOYSTICKRIGHT_DOWN, SEQ_TYPE_STANDARD, rightdownseq);
}
void joystick_assignment_helper::choose_primary_stick(
input_item_id (&stickaxes)[2][2],
input_item_id leftx,
input_item_id lefty,
input_item_id rightx,
input_item_id righty)
{
if ((ITEM_ID_INVALID != leftx) && (ITEM_ID_INVALID != lefty))
{
// left stick has both axes, make it primary
stickaxes[0][0] = leftx;
stickaxes[0][1] = lefty;
stickaxes[1][0] = rightx;
stickaxes[1][1] = righty;
}
else if ((ITEM_ID_INVALID != rightx) && (ITEM_ID_INVALID != righty))
{
// right stick has both axes, make it primary
stickaxes[0][0] = rightx;
stickaxes[0][1] = righty;
stickaxes[1][0] = leftx;
stickaxes[1][1] = lefty;
}
else if (ITEM_ID_INVALID != leftx)
{
// degenerate case - left X and possibly right X or Y
stickaxes[0][0] = leftx;
stickaxes[0][1] = righty;
stickaxes[1][0] = rightx;
stickaxes[1][1] = ITEM_ID_INVALID;
}
else if ((ITEM_ID_INVALID != rightx) || (ITEM_ID_INVALID != lefty))
{
// degenerate case - right X and possibly left Y, or one or two Y axes
stickaxes[0][0] = rightx;
stickaxes[0][1] = lefty;
stickaxes[1][0] = ITEM_ID_INVALID;
stickaxes[1][1] = righty;
}
else
{
// degenerate case - one Y axis at most
stickaxes[0][0] = ITEM_ID_INVALID;
stickaxes[0][1] = righty;
stickaxes[1][0] = ITEM_ID_INVALID;
stickaxes[1][1] = ITEM_ID_INVALID;
}
}
} // namespace osd

View File

@ -0,0 +1,118 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
//============================================================
//
// assignmenthelper.h - input assignment setup helper
//
//============================================================
#ifndef MAME_OSD_INPUT_ASSIGNMENTHELPER_H
#define MAME_OSD_INPUT_ASSIGNMENTHELPER_H
#pragma once
#include "interface/inputcode.h"
#include "interface/inputdev.h"
#include <initializer_list>
namespace osd {
class joystick_assignment_helper
{
protected:
static constexpr input_code make_code(
input_item_class itemclass,
input_item_modifier modifier,
input_item_id item)
{
return input_code(DEVICE_CLASS_JOYSTICK, 0, itemclass, modifier, item);
}
static bool add_assignment(
input_device::assignment_vector &assignments,
ioport_type fieldtype,
input_seq_type seqtype,
input_item_class itemclass,
input_item_modifier modifier,
std::initializer_list<input_item_id> items);
static bool add_button_assignment(
input_device::assignment_vector &assignments,
ioport_type field_type,
std::initializer_list<input_item_id> items);
static bool add_button_pair_assignment(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id button1,
input_item_id button2);
static bool add_axis_inc_dec_assignment(
input_device::assignment_vector &assignments,
ioport_type field_type,
input_item_id button_dec,
input_item_id button_inc);
static bool add_axis_pair_assignment(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id axis);
static bool consume_button_pair(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id &button1,
input_item_id &button2);
static bool consume_trigger_pair(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id &axis1,
input_item_id &axis2);
static bool consume_axis_pair(
input_device::assignment_vector &assignments,
ioport_type field1,
ioport_type field2,
input_item_id &axis);
static void add_directional_assignments(
input_device::assignment_vector &assignments,
input_item_id xaxis,
input_item_id yaxis,
input_item_id leftswitch,
input_item_id rightswitch,
input_item_id upswitch,
input_item_id downswitch);
static void add_twin_stick_assignments(
input_device::assignment_vector &assignments,
input_item_id leftx,
input_item_id lefty,
input_item_id rightx,
input_item_id righty,
input_item_id leftleft,
input_item_id leftright,
input_item_id leftup,
input_item_id leftdown,
input_item_id rightleft,
input_item_id rightright,
input_item_id rightup,
input_item_id rightdown);
static void choose_primary_stick(
input_item_id (&stickaxes)[2][2],
input_item_id leftx,
input_item_id lefty,
input_item_id rightx,
input_item_id righty);
};
} // namespace osd
#endif // MAME_OSD_INPUT_ASSIGNMENTHELPER_H

Some files were not shown because too many files have changed in this diff Show More