summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2020-12-16 02:18:52 +1100
committer Vas Crabb <vas@vastheman.com>2020-12-16 02:18:52 +1100
commit503332a9867f9aa27fc77cd9e762626d22d213ef (patch)
treee60fba6664a3d980d5f62846982bde381a25c3f7
parentb5f78fe38358b68fc54416328f764cf4e2bf3333 (diff)
-Lua cleanup and documentation migration checkpoint.
* Cleaned up some more of the Lua inteface. Mostly replacing methods with properties, some consistency fixes, a few renames, some more exposed functionality, and a couple of properties that have no business being set from scripts made read-only. * Moved a lot more Lua documentation out of source comments into the documentation, and expanded on it in the process. * Got more UI code out of the input manager. * Changed input sequence poller to a polymorphic class where you specify your intention upfront. * Changed the cheat plugin to use UI Clear to clear hotkey assignments and leave them unchanged if the user starts assignment but doesn't press any switches. * Ported AJR's fix for over-eager double-click recognition from SDL to Windows OSD. -goldnpkr.cpp: Cleaned up inputs, using standard keyout and payout types and key assignments.
-rw-r--r--docs/source/techspecs/luareference.rst1195
-rw-r--r--docs/source/techspecs/memory.rst2
-rw-r--r--plugins/autofire/autofire_menu.lua13
-rw-r--r--plugins/cheat/init.lua30
-rw-r--r--plugins/cheatfind/init.lua8
-rw-r--r--plugins/gdbstub/init.lua4
-rw-r--r--src/emu/input.cpp198
-rw-r--r--src/emu/input.h7
-rw-r--r--src/frontend/mame/iptseqpoll.cpp437
-rw-r--r--src/frontend/mame/iptseqpoll.h102
-rw-r--r--src/frontend/mame/luaengine.cpp44
-rw-r--r--src/frontend/mame/luaengine.ipp3
-rw-r--r--src/frontend/mame/luaengine_debug.cpp115
-rw-r--r--src/frontend/mame/luaengine_input.cpp248
-rw-r--r--src/frontend/mame/luaengine_mem.cpp270
-rw-r--r--src/frontend/mame/ui/inputmap.cpp22
-rw-r--r--src/frontend/mame/ui/inputmap.h2
-rw-r--r--src/frontend/mame/ui/pluginopt.cpp1
-rw-r--r--src/frontend/mame/ui/state.cpp5
-rw-r--r--src/frontend/mame/ui/state.h4
-rw-r--r--src/frontend/mame/ui/ui.cpp114
-rw-r--r--src/frontend/mame/ui/ui.h3
-rw-r--r--src/mame/drivers/goldnpkr.cpp364
-rw-r--r--src/mame/layout/mdndclab.lay14
-rw-r--r--src/osd/windows/window.cpp4
25 files changed, 2096 insertions, 1113 deletions
diff --git a/docs/source/techspecs/luareference.rst b/docs/source/techspecs/luareference.rst
index ac606f02293..c61939daf0b 100644
--- a/docs/source/techspecs/luareference.rst
+++ b/docs/source/techspecs/luareference.rst
@@ -58,6 +58,989 @@ c:index_of(v)
value.
+.. _luareference-mem:
+
+Memory system
+-------------
+
+MAME’s Lua interface exposes various memory system objects, including address
+spaces, memory shares, memory banks, and memory regions. Scripts can read from
+and write to the emulated memory system.
+
+.. _luareference-mem-manager:
+
+Memory manager
+~~~~~~~~~~~~~~
+
+Wraps MAME’s ``memory_manager`` class, which allows the memory shares, banks and
+regions in a system to be enumerated.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():memory()
+ Gets the global memory manager instance for the emulated system.
+
+Properties
+^^^^^^^^^^
+
+memory.shares[]
+ The :ref:`memory shares <luareference-mem-share>` in the system, indexed by
+ absolute tag. The ``at`` and ``index_of`` methods have O(n) complexity; all
+ other supported operations have O(1) complexity.
+memory.banks[]
+ The :ref:`memory banks <luareference-mem-bank>` in the system, indexed by
+ absolute tag. The ``at`` and ``index_of`` methods have O(n) complexity; all
+ other supported operations have O(1) complexity.
+memory.regions[]
+ The :ref:`memory regions <luareference-mem-region>` in the system, indexed
+ by absolute tag. The ``at`` and ``index_of`` methods have O(n) complexity;
+ all other supported operations have O(1) complexity.
+
+.. _luareference-mem-space:
+
+Address space
+~~~~~~~~~~~~~
+
+Wraps MAME’s ``address_space`` class, which represent’s an address space
+belonging to a device.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag].spaces[name]
+ Gets the address space with the specified name for a given device. Note
+ that names are specific to the device type.
+
+Methods
+^^^^^^^
+
+space:read_i{8,16,32,64}(addr)
+ Reads a signed integer value of the size in bits from the specified address.
+space:read_u{8,16,32,64}(addr)
+ Reads an unsigned integer value of the size in bits from the specified
+ address.
+space:write_i{8,16,32,64}(addr, val)
+ Writes a signed integer value of the size in bits to the specified address.
+space:write_u{8,16,32,64}(addr, val)
+ Writes an unsigned integer value of the size in bits to the specified
+ address.
+space:readv_i{8,16,32,64}(addr)
+ Reads a signed integer value of the size in bits from the specified virtual
+ address. The address is translated with the debug read intent. Returns
+ zero if address translation fails.
+space:readv_u{8,16,32,64}(addr)
+ Reads an unsigned integer value of the size in bits from the specified
+ virtual address. The address is translated with the debug read intent.
+ Returns zero if address translation fails.
+space:writev_i{8,16,32,64}(addr, val)
+ Writes a signed integer value of the size in bits to the specified virtual
+ address. The address is translated with the debug write intent. Does not
+ write if address translation fails.
+space:writev_u{8,16,32,64}(addr, val)
+ Writes an unsigned integer value of the size in bits to the specified
+ virtual address. The address is translated with the debug write intent.
+ Does not write if address translation fails.
+space:read_direct_i{8,16,32,64}(addr)
+ Reads a signed integer value of the size in bits from the specified address
+ one byte at a time by obtaining a read pointer for each byte address. If
+ a read pointer cannot be obtained for a byte address, the corresponding
+ result byte will be zero.
+space:read_direct_u{8,16,32,64}(addr)
+ Reads an unsigned integer value of the size in bits from the specified
+ address one byte at a time by obtaining a read pointer for each byte
+ address. If a read pointer cannot be obtained for a byte address, the
+ corresponding result byte will be zero.
+space:write_direct_i{8,16,32,64}(addr, val)
+ Writes a signed integer value of the size in bits to the specified address
+ one byte at a time by obtaining a write pointer for each byte address. If
+ a write pointer cannot be obtained for a byte address, the corresponding
+ byte will not be written.
+space:write_direct_u{8,16,32,64}(addr, val)
+ Writes an unsigned integer value of the size in bits to the specified
+ address one byte at a time by obtaining a write pointer for each byte
+ address. If a write pointer cannot be obtained for a byte address, the
+ corresponding byte will not be written.
+space:read_range(start, end, width, [step])
+ Reads a range of addresses as a binary string. The end address must be
+ greater than or equal to the start address. The width must be 8, 16, 30 or
+ 64. If the step is provided, it must be a positive number of elements.
+
+Properties
+^^^^^^^^^^
+
+space.name (read-only)
+ The display name for the address space.
+space.shift (read-only)
+ The address address granularity for the address space specified as the shift
+ required to translate a byte address to a native address. Positive values
+ shift towards the most significant bit (left) and negative values shift
+ towards the least significant bit (right).
+space.index (read-only)
+ The zero-based space index. Some space indices have special meanings for
+ the debugger.
+space.address_mask (read-only)
+ The address mask for the space.
+space.data_width (read-only)
+ The data width for the space in bits.
+space.endianness (read-only)
+ The Endianness of the space (``"big"`` or ``"little"``).
+space.map (read-only)
+ The configured :ref:`address map <luareference-mem-map>` for the space or
+ ``nil``.
+
+.. _luareference-mem-map:
+
+Address map
+~~~~~~~~~~~
+
+Wraps MAME’s ``address_map`` class, used to configure handlers for an address
+space.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag].spaces[name].map
+ Gets the configured address map for an address space, or ``nil`` if no map
+ is configured.
+
+Properties
+^^^^^^^^^^
+
+map.spacenum (read-only)
+ The address space number of the address space the map is associated with
+map.device (read-only)
+ The device that owns the address space the map is associated with.
+map.unmap_value (read-only)
+ The constant value to return from unmapped reads.
+map.global_mask (read-only)
+ Global mask to be applied to all addresses when accessing the space.
+map.entries[] (read-only)
+ The configured :ref:`entries <luareference-mem-mapentry>` in the address
+ map. Uses 1-based integer indices. The index operator and the ``at``
+ method have O(n) complexity.
+
+.. _luareference-mem-mapentry:
+
+Address map entry
+~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``address_map_entry`` class, representing an entry in a configured
+address map.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag].spaces[name].map.entries[index]
+ Gets an entry from the configured map for an address space.
+
+Properties
+^^^^^^^^^^
+
+entry.address_start (read-only)
+ Start address of the entry’s range.
+entry.address_end (read-only)
+ End address of the entry’s range (inclusive).
+entry.address_mirror (read-only)
+ Address mirror bits.
+entry.address_end (read-only)
+ Address mask bits. Only valid for handlers.
+entry.mask (read-only)
+ Lane mask, indicating which data lines on the bus are connected to the
+ handler.
+entry.cswidth (read-only)
+ The trigger width for a handler that isn’t connected to all the data lines.
+entry.read (read-only)
+ :ref:`Additional data <luareference-memory-handlerdata>` for the read
+ handler.
+entry.write (read-only)
+ :ref:`Additional data <luareference-memory-handlerdata>` for the write
+ handler.
+entry.share (read-only)
+ Memory share tag for making RAM entries accessible or ``nil``.
+entry.address_end (read-only)
+ Explicit memory region tag for ROM entries, or ``nil``.
+entry.region_offset (read-only)
+ Starting offset in memory region for ROM entries.
+
+.. _luareference-memory-handlerdata:
+
+Address map handler data
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``map_handler_data`` class, which provides configuration data to
+handlers in address maps.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag].spaces[name].map.entries[index].read
+ Gets the read handler data for an address map entry.
+manager:machine().devices[tag].spaces[name].map.entries[index].write
+ Gets the write handler data for an address map entry.
+
+Properties
+^^^^^^^^^^
+
+data.handlertype (read-only)
+ Handler type. Will be one of ``"none"``, ``"ram"``, ``"rom"``, ``"nop"``,
+ ``"unmap"``, ``"delegate"``, ``"port"``, ``"bank"``, ``"submap"``, or
+ ``"unknown"``. Note that multiple handler type values can yield
+ ``"delegate"`` or ``"unknown"``.
+data.bits (read-only)
+ Data width for the handler in bits.
+data.name (read-only)
+ Display name for the handler, or ``nil``.
+data.tag (read-only)
+ Tag for I/O ports and memory banks, or ``nil``.
+
+.. _luareference-mem-share:
+
+Memory share
+~~~~~~~~~~~~
+
+Wraps MAME’s ``memory_share`` class, representing a named allocated memory zone.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():memory().shares[tag]
+ Gets a memory share by absolute tag, or ``nil`` if no such memory share
+ exists.
+manager:machine().devices[tag]:memshare(tag)
+ Gets a memory share by tag relative to a device, or ``nil`` if no such
+ memory share exists.
+
+Methods
+^^^^^^^
+
+share:read_i{8,16,32,64}(offs)
+ Reads a signed integer value of the size in bits from the specified offset
+ in the memory share.
+share:read_u{8,16,32,64}(offs)
+ Reads an unsigned integer value of the size in bits from the specified
+ offset in the memory share.
+share:write_i{8,16,32,64}(offs, val)
+ Writes a signed integer value of the size in bits to the specified offset in
+ the memory share.
+share:write_u{8,16,32,64}(offs, val)
+ Writes an unsigned integer value of the size in bits to the specified offset
+ in the memory share.
+
+Properties
+^^^^^^^^^^
+
+share.tag (read-only)
+ The absolute tag of the memory share.
+share.size (read-only)
+ The size of the memory share in bytes.
+share.length (read-only)
+ The length of the memory share in native width elements.
+share.endianness (read-only)
+ The Endianness of the memory share (``"big"`` or ``"little"``).
+share.bitwidth (read-only)
+ The native element width of the memory share in bits.
+share.bytewidth (read-only)
+ The native element width of the memory share in bytes.
+
+.. _luareference-mem-bank:
+
+Memory bank
+~~~~~~~~~~~
+
+Wraps MAME’s ``memory_bank`` class, representing a named memory zone
+indirection.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():memory().banks[tag]
+ Gets a memory region by absolute tag, or ``nil`` if no such memory bank
+ exists.
+manager:machine().devices[tag]:membank(tag)
+ Gets a memory region by tag relative to a device, or ``nil`` if no such
+ memory bank exists.
+
+Properties
+^^^^^^^^^^
+
+bank.tag (read-only)
+ The absolute tag of the memory bank.
+bank.entry (read/write)
+ The currently selected zero-based entry number.
+
+.. _luareference-mem-region:
+
+Memory region
+~~~~~~~~~~~~~
+
+Wraps MAME’s ``memory_region`` class, representing a memory region used to store
+read-only data like ROMs or the result of fixed decryptions.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():memory().regions[tag]
+ Gets a memory region by absolute tag, or ``nil`` if no such memory region
+ exists.
+manager:machine().devices[tag]:memregion(tag)
+ Gets a memory region by tag relative to a device, or ``nil`` if no such
+ memory region exists.
+
+Methods
+^^^^^^^
+
+region:read_i{8,16,32,64}(offs)
+ Reads a signed integer value of the size in bits from the specified offset
+ in the memory region.
+region:read_u{8,16,32,64}(offs)
+ Reads an unsigned integer value of the size in bits from the specified
+ offset in the memory region.
+region:write_i{8,16,32,64}(offs, val)
+ Writes a signed integer value of the size in bits to the specified offset in
+ the memory region.
+region:write_u{8,16,32,64}(offs, val)
+ Writes an unsigned integer value of the size in bits to the specified offset
+ in the memory region.
+
+Properties
+^^^^^^^^^^
+
+region.tag (read-only)
+ The absolute tag of the memory region.
+region.size (read-only)
+ The size of the memory region in bytes.
+region.length (read-only)
+ The length of the memory region in native width elements.
+region.endianness (read-only)
+ The Endianness of the memory region (``"big"`` or ``"little"``).
+region.bitwidth (read-only)
+ The native element width of the memory region in bits.
+region.bytewidth (read-only)
+ The native element width of the memory region in bytes.
+
+
+.. _luareference-input:
+
+Input system
+------------
+
+Allows scripts to get input from the user, and access I/O ports in the emulated
+system.
+
+.. _luareference-input-ioportman:
+
+I/O port manager
+~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``ioport_manager`` class, which provides access to emulated I/O
+ports and handles input configuration.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():ioport()
+ Gets the global I/O port manager instance for the emulated machine.
+
+Methods
+^^^^^^^
+
+ioport:count_players()
+ Returns the number of player controllers in the system.
+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.
+
+ 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.
+
+Properties
+^^^^^^^^^^
+
+ioport.ports[]
+ Gets the emulated :ref:`I/O ports <luareference-input-ioport>` in the
+ system. Keys are absolute tags. The ``at`` and ``index_of`` methods have
+ O(n) complexity; all other supported operations have O(1) complexity.
+ioport.natkeyboard
+ Gets the :ref:`natural keyboard manager <luareference-input-natkbd>`, used
+ for controlling keyboard and keypad input to the emulated system.
+
+.. _luareference-input-natkbd:
+
+Natural keyboard manager
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``natural_keyboard`` class, which manages emulated keyboard and
+keypad inputs.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():ioport().natkeyboard
+ Gets the global natural keyboard manager instance for the emulated machine.
+
+Methods
+^^^^^^^
+
+natkeyboard:post(text)
+ Post literal text to the emulated machine. The machine must have keyboard
+ inputs with character bindings, and the correct keyboard input device must
+ be enabled.
+natkeyboard:post_coded(text)
+ Post text to the emulated machine. Brace-enclosed codes are interpreted in
+ the text. The machine must have keyboard inputs with character bindings,
+ and the correct keyboard input device must be enabled.
+
+ The recognised codes are ``{BACKSPACE}``, ``{BS}``, ``{BKSP}``, ``{DEL}``,
+ ``{DELETE}``, ``{END}``, ``{ENTER}``, ``{ESC}``, ``{HOME}``, ``{INS}``,
+ ``{INSERT}``, ``{PGDN}``, ``{PGUP}``, ``{SPACE}``, ``{TAB}``, ``{F1}``,
+ ``{F2}``, ``{F3}``, ``{F4}``, ``{F5}``, ``{F6}``, ``{F7}``, ``{F8}``,
+ ``{F9}``, ``{F10}``, ``{F11}``, ``{F12}``, and ``{QUOTE}``.
+natkeyboard:paste()
+ Post the contents of the host clipboard to the emulated machine. The
+ machine must have keyboard inputs with character bindings, and the correct
+ keyboard input device must be enabled.
+natkeyboard:dump()
+ Returns a string with a human-readable description of the keyboard and
+ keypad input devices in the system, whether they are enabled, and their
+ character bindings.
+
+Properties
+^^^^^^^^^^
+
+natkeyboard.empty (read-only)
+ A Boolean indicating whether the natural keyboard manager’s input buffer is
+ empty.
+natkeyboard.full (read-only)
+ A Boolean indicating whether the natural keyboard manager’s input buffer is
+ full.
+natkeyboard.can_post (read-only)
+ A Boolean indicating whether the emulated system supports posting character
+ data via the natural keyboard manager.
+natkeyboard.is_posting (read-only)
+ A Boolean indicating whether posted character data is currently being
+ delivered to the emulated system.
+natkeyboard.in_use (read/write)
+ A Boolean indicating whether “natural keyboard” mode is enabled. When
+ “natural keyboard” mode is enabled, the natural keyboard manager translates
+ host character input to emulated system keystrokes.
+natkeyboard.keyboards[]
+ Gets the :ref:`keyboard/keypad input devices <luareference-input-kbddev>` in
+ the emulated system, indexed by absolute device tag. Index get has O(n)
+ complexity; all other supported operations have O(1) complexity.
+
+.. _luareference-input-kbddev:
+
+Keyboard input device
+~~~~~~~~~~~~~~~~~~~~~
+
+Represents a keyboard or keypad input device managed by the
+:ref:`natural keyboard manager <luareference-input-natkbd>`.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():ioport().natkeyboard.keyboards[tag]
+ Gets the keyboard input device with the specified tag, or ``nil`` if the tag
+ does not correspond to a keyboard input device.
+
+Properties
+^^^^^^^^^^
+
+keyboard.device (read-only)
+ The underlying device.
+keyboard.tag (read-only)
+ The absolute tag of the underlying device.
+keyboard.basetag (read-only)
+ The last component of the tag of the underlying device, or ``"root"`` for
+ the root machine device.
+keyboard.name (read-only)
+ The human-readable description of the underlying device type.
+keyboard.shortname (read-only)
+ The identifier for the underlying device type.
+keyboard.is_keypad (read-only)
+ A Boolean indicating whether the underlying device has keypad inputs but no
+ keyboard inputs. This is used when determining which keyboard input devices
+ should be enabled by default.
+keyboard.enabled (read/write)
+ A Boolean indicating whether the device’s keyboard and/or keypad inputs are
+ enabled.
+
+.. _luareference-input-ioport:
+
+I/O port
+~~~~~~~~
+
+Wraps MAME’s ``ioport_port`` class, representing an emulated I/O port.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():ioport().ports[tag]
+ Gets an emulated I/O port by absolute tag, or ``nil`` if the tag does not
+ correspond to an I/O port.
+manager:machine().devices[devtag]:ioport(porttag)
+ Gets an emulated I/O port by tag relative to a device, or ``nil`` if no such
+ I/O port exists.
+
+Methods
+^^^^^^^
+
+port:read()
+ Read the current input value. Returns a 32-bit integer.
+port:write(value, mask)
+ Write to the I/O port output fields that are set in the specified mask. The
+ value and mask must be 32-bit integers. Note that this does not set values
+ for input fields.
+port:field(mask)
+ Get the first :ref:`I/O port field <luareference-input-field>` corresponding
+ to the bits that are set in the specified mask, or ``nil`` if there is no
+ corresponding field.
+
+Properties
+^^^^^^^^^^
+
+port.device (read-only)
+ The device that owns the I/O port.
+port.tag (read-only)
+ The absolute tag of the I/O port
+port.active (read-only)
+ A mask indicating which bits of the I/O port correspond to active fields
+ (i.e. not unused or unassigned bits).
+port.live (read-only)
+ The live state of the I/O port.
+port.fields[] (read-only)
+ Gets a table of :ref:`fields <luareference-input-field>` indexed by name.
+
+.. _luareference-input-field:
+
+I/O port field
+~~~~~~~~~~~~~~
+
+Wraps MAME’s ``ioport_field`` class, representing a field within an I/O port.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():ioport().ports[tag]:field[mask]
+ Gets a field for the given port by bit mask.
+manager:machine():ioport().ports[tag].fields[name]
+ Gets a field for the given port by display name.
+
+Methods
+^^^^^^^
+
+field:set_value(value)
+ Set the value of the I/O port field. For digital fields, the value is
+ compared to zero to determine whether the field should be active; for
+ analog fields, the value must be right-aligned and in the correct range.
+field:set_input_seq(seqtype, seq)
+ Set the input sequence for the specified sequence type. This is used to
+ configure per-machine input settings. The sequence type must be
+ ``"standard"``, ``"increment"`` or ``"decrement"``.
+field:input_seq(seq_type)
+ Get the configured input sequence for the specified sequence type. This
+ gets per-machine input settings. The sequence type must be ``"standard"``,
+ ``"increment"`` or ``"decrement"``.
+field:set_default_input_seq(seq_type, seq)
+ Set the default input sequence for the specified sequence type. This is
+ used to configure general input settings. The sequence type must be
+ ``"standard"``, ``"increment"`` or ``"decrement"``.
+field:default_input_seq(seq_type)
+ Gets the default input sequence for the specified sequence type. This is
+ gets general input settings. The sequence type must be ``"standard"``,
+ ``"increment"`` or ``"decrement"``.
+field:keyboard_codes(shift)
+ Gets a table of characters corresponding to the field for the specified
+ shift state. The shift state is a bit mask of active shift keys.
+
+Properties
+^^^^^^^^^^
+
+field.device (read-only)
+ The device that owns the port that the field belongs to.
+field.port (read-only)
+ The :ref:`I/O port <luareference-input-ioport>` that the field belongs to.
+field.live (read-only)
+ The :ref:`live state <luareference-input-fieldlive>` of the field.
+field.type (read-only)
+ The input type of the field. This is an enumerated value.
+field.name (read-only)
+ The display name for the field.
+field.default_name (read-only)
+ The name for the field from the emulated system’s configuration (cannot be
+ overridden by scripts or plugins).
+field.player (read-only)
+ Zero-based player number for the field.
+field.mask (read-only)
+ Bits in the I/O port corresponding to this field.
+field.defvalue (read-only)
+ The field’s default value
+field.sensitivity (read-only)
+ The sensitivity or gain for analog fields
+field.way (read-only)
+ The number of directions allowed by the restrictor plate/gate for a digital
+ joystick, or zero (0) for other inputs.
+field.type_class (read-only)
+ The type class for the input field – one of ``"keyboard"``,
+ ``"controller"``, ``"config"``, ``"dipswitch"`` or ``"misc"``.
+field.is_analog (read-only)
+ A Boolean indicating whether the field is an analog axis or positional
+ control.
+field.is_digital_joystick (read-only)
+ A Boolean indicating whether the field corresponds to a digital joystick
+ switch.
+field.enabled (read-only)
+ A Boolean indicating whether the field is enabled.
+field.optional (read-only)
+ A Boolean indicating whether the field is optional and not required to use
+ the emulated system.
+field.cocktail (read-only)
+ A Boolean indicating whether the field is only used when the system is
+ configured for a cocktail table cabinet.
+field.toggle (read-only)
+ A Boolean indicating whether the field corresponds to a hardware toggle
+ switch or push-on, push-off button.
+field.rotated (read-only)
+ A Boolean indicating whether the field corresponds to a control that is
+ rotated relative its standard orientation.
+field.analog_reverse (read-only)
+ A Boolean indicating whether the field corresponds to an analog control that
+ increases in the opposite direction to the convention (e.g. larger values
+ when a pedal is released or a joystick is moved to the left).
+field.analog_reset (read-only)
+ A Boolean indicating whether the field corresponds to an incremental
+ position input (e.g. a dial or trackball axis) that should be reset to zero
+ for every video frame.
+field.analog_wraps (read-only)
+ A Boolean indicating whether the field corresponds to an analog input that
+ wraps from one end of its range to the other (e.g. an incremental position
+ input like a dial or trackball axis).
+field.analog_invert (read-only)
+ A Boolean indicating whether the field corresponds to an analog input that
+ has its value ones-complemented.
+field.impulse (read-only)
+ A Boolean indicating whether the field corresponds to a digital input that
+ activates for a fixed amount of time.
+field.crosshair_scale (read-only)
+ The scale factor for translating the field’s range to crosshair position. A
+ value of one (1) translates the field’s full range to the full width or
+ height the screen.
+field.crosshair_offset (read-only)
+ The offset for translating the field’s range to crosshair position.
+field.user_value (read/write)
+ The value for DIP switch or configuration settings.
+field.settings[] (read-only)
+ Gets a table of the currently enabled settings for a DIP switch or
+ configuration field, indexed by value.
+
+.. _luareference-input-fieldlive:
+
+Live I/O port field state
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``ioport_field_live`` class, representing the live state of an I/O
+port field.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():ioport().ports[tag]:field(mask).live
+ Gets the live state for an I/O port field.
+
+Properties
+^^^^^^^^^^
+
+live.name
+ Display name for the field.
+
+.. _luareference-input-inputman:
+
+Input manager
+~~~~~~~~~~~~~
+
+Wraps MAME’s ``input_manager`` class, which reads host input devices and checks
+whether configured inputs are active.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():input()
+ Gets the global input manager instance for the emulated system.
+
+Methods
+^^^^^^^
+
+input:code_value(code)
+ Gets the current value for the host input corresponding to the specified
+ code. Returns a signed integer value, where zero is the neutral position.
+input:code_pressed(code)
+ Returns a Boolean indicating whether the host input corresponding to the
+ specified code has a non-zero value (i.e. it is not in the neutral
+ position).
+input:code_pressed_once(code)
+ Returns a Boolean indicating whether the host input corresponding to the
+ specified code has moved away from the neutral position since the last time
+ it was checked using this function. The input manager can track a limited
+ number of inputs this way.
+input:code_name(code)
+ Get display name for an input code.
+input:code_to_token(code)
+ Get token string for an input code. This should be used when saving
+ configuration.
+input:code_from_token(token)
+ Convert a token string to an input code. Returns the invalid input code if
+ the token is not valid or belongs to an input device that is not present.
+input:seq_pressed(seq)
+ Returns a Boolen indicating whether the supplied input sequence is currently
+ pressed.
+input:seq_clean(seq)
+ Remove invalid elements from the supplied input sequence. Returns the new,
+ cleaned input sequence.
+input:seq_name(seq)
+ Get display text for an inptu sequence.
+input:seq_to_tokens(seq)
+ Convert an input sequence to a token string. This should be used when
+ saving configuration.
+input:seq_from_tokens(tokens)
+ Convert a token string to an input sequence. This should be used when
+ loading configuration.
+input:axis_code_poller()
+ Returns an :ref:`input code poller <luareference-input-codepoll>` for
+ obtaining an analog host input code.
+input:switch_code_poller()
+ Returns an :ref:`input code poller <luareference-input-codepoll>` for
+ obtaining a host switch input code.
+input:keyboard_code_poller()
+ Returns an :ref:`input code poller <luareference-input-codepoll>` for
+ obtaining a host switch input code that only considers keyboard input
+ devices.
+input:axis_sequence_poller()
+ Returns an :ref:`input sequence poller <luareference-input-seqpoll>` for
+ obtaining an input sequence for configuring an analog input.
+input:axis_sequence_poller()
+ Returns an :ref:`input sequence poller <luareference-input-seqpoll>` for
+ obtaining an input sequence for configuring a digital input.
+
+Properties
+^^^^^^^^^^
+
+input.device_classes[] (read-only)
+ Gets a table of host
+ :ref:`input device classes <luareference-input-devclass>` indexed by name.
+
+.. _luareference-input-codepoll:
+
+Input code poller
+~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``input_code_poller`` class, used to poll for host inputs being
+activated.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():input():axis_code_poller()
+ Returns an input code poller that polls for analog inputs being activated.
+manager:machine():input():switch_code_poller()
+ Returns an input code poller that polls for host switch inputs being
+ activated.
+manager:machine():input():keyboard_code_poller()
+ Returns an input code poller that polls for host switch inputs being
+ activated, only considering keyboard input devices.
+
+Methods
+^^^^^^^
+
+poller:reset()
+ Resets the polling logic. Active switch inputs are cleared and initial
+ analog input positions are set.
+poller:poll()
+ Returns an input code corresponding to the first relevant host input that
+ has been activated since the last time the method was called. Returns the
+ invalid input code if no relevant input has been activated.
+
+.. _luareference-input-seqpoll:
+
+Input sequence poller
+~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``input_sequence_poller`` poller class, which allows users to
+assign host input combinations to emulated inputs and other actions.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():input():axis_sequence_poller()
+ Returns an input sequence poller for assigning host inputs to an analog
+ input.
+manager:machine():input():switch_sequence_poller()
+ Returns an input sequence poller for assigning host inputs to a switch
+ input.
+
+Methods
+^^^^^^^
+
+poller:start([seq])
+ Start polling. If a sequence is supplied, it is used as a starting
+ sequence: for analog inputs, the user can cycle between the full range, and
+ the positive and negative portions of an axis; for switch inputs, an “or”
+ code is appended and the user can add an alternate host input combination.
+poller:poll()
+ Polls for for user input and updates the sequence if appropriate. Returns a
+ Boolean indicating whether sequence input is complete. If this method
+ returns false, you should continue polling.
+
+Properties
+^^^^^^^^^^
+
+poller.sequence (read-only)
+ The current input sequence. This is updated while polling. It is possible
+ for the sequence to become invalid.
+poller.valid (read-only)
+ A Boolean indicating whether the current input sequence is valid.
+poller.modified (read-only)
+ A Boolean indicating whether the sequence was changed by any user input
+ since starting polling.
+
+.. _luareference-input-devclass:
+
+Host input device class
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``input_class`` class, representing a category of host input
+devices (e.g. keyboards or joysticks).
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():input().device_classes[name]
+ Gets an input device class by name.
+
+Properties
+^^^^^^^^^^
+
+devclass.name (read-only)
+ The device class name.
+devclass.enabled (read-only)
+ A Boolean indicating whether the device class is enabled.
+devclass.multi (read-only)
+ A Boolean indicating whether the device class supports multiple devices, or
+ inputs from all devices in the class are combined and treated as a single
+ device.
+devclass.devices[] (read-only)
+ Gets a table of :ref:`host input devices <luareference-input-inputdev>` in
+ the class. Keys are one-based indices.
+
+.. _luareference-input-inputdev:
+
+Host input device
+~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``input_device`` class, representing a host input device.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():input().device_classes[name].devices[index]
+ Gets a specific host input device.
+
+Properties
+^^^^^^^^^^
+
+inputdev.name (read-only)
+ Display name for the device. This is not guaranteed to be unique.
+inputdev.id (read-only)
+ Unique identifier string for the device. This may not be human-readable.
+inputdev.devindex (read-only)
+ Device index within the device class. This is not necessarily the same as
+ the index in the ``devices`` property of the device class – the ``devindex``
+ indices may not be contiguous.
+inputdev.items (read-only)
+ Gets a table of :ref:`input items <luareference-input-inputitem>`, indexed
+ by item ID. The item ID is an enumerated value.
+
+.. _luareference-input-inputitem:
+
+Host input device item
+~~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``input_device_item`` class, representing a single host input (e.g.
+a key, button, or axis).
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():input().device_classes[name].devices[index].items[id]
+ Gets an individual host input item. The item ID is an enumerated value.
+
+Properties
+^^^^^^^^^^
+
+item.name (read-only)
+ The display name of the input item. Note that this is just the name of the
+ item itself, and does not include the device name. The full display name
+ for the item can be obtained by calling the ``code_name`` method on the
+ :ref:`input manager <luareference-input-inputman>` with the item’s code.
+item.code (read-only)
+ The input item’s identification code. This is used by several
+ :ref:`input manager <luareference-input-inputman>` methods.
+item.token (read-only)
+ The input item’s token string. Note that this is a token fragment for the
+ item itself, and does not include the device portion. The full token for
+ the item can be obtained by calling the ``code_to_token`` method on the
+ :ref:`input manager <luareference-input-inputman>` with the item’s code.
+item.current (read-only)
+ The item’s current value. This is a signed integer where zero is the
+ neutral position.
+
+.. _luareference-input-uiinput:
+
+UI input manager
+~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``ui_input_manager`` class, which is used for high-level input.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():uiinput()
+ Gets the global UI input manager instance for the machine.
+
+Methods
+^^^^^^^
+
+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
+ position is in host pixels, where zero is at the top/left. The button state
+ is a Boolean indicating whether the primary mouse button is pressed.
+
+ If the mouse pointer is not over one of MAME’s windows, this may return the
+ position and render target from when the mouse pointer was most recently
+ over one of MAME’s windows. The render target may be ``nil`` if the mouse
+ pointer is not over one of MAME’s windows.
+uiinput:pressed(type)
+ Returns a Boolean indicating whether the specified UI input has been
+ pressed. The input type is an enumerated value.
+uiinput:pressed_repeat(type, speed)
+ Returns a Boolean indicating whether the specified UI input has been
+ pressed or auto-repeat has been triggered at the specified speed. The input
+ type is an enumerated value; the speed is an interval in sixtieths of a
+ second.
+
+Properties
+^^^^^^^^^^
+
+uiinput.presses_enabled (read/write)
+ Whether the UI input manager will check for UI inputs frame updates.
+
+
.. _luareference-render:
Render system
@@ -312,10 +1295,10 @@ container.yscale (read/write)
The container’s Y scale factor. This is a floating-point number.
container.xoffset (read/write)
The container’s X offset. This is a floating-point number where one (1)
- represents the X size of the container.
+ corresponds to the X size of the container.
container.yoffset (read/write)
The container’s Y offset. This is a floating-point number where one (1)
- represents the Y size of the container.
+ corresponds to the Y size of the container.
container.is_empty (read-only)
A Boolean indicating whether the container has no items.
@@ -580,3 +1563,211 @@ item.element_state (read-only)
item.animation_state (read-only)
Get the current animation state. This will call the animation state
callback function to handle bindings.
+
+
+.. _luareference-debug:
+
+Debugger
+--------
+
+Some of MAME’s core debugging features can be controlled from Lua script. The
+debugger must be enabled to use the debugging features (usually by passing
+``-debug`` on the command line).
+
+.. _luareference-debug-manager:
+
+Debugger manager
+~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``debugger_manager`` class, providing the main interface to control
+the debugger.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine():debugger()
+ Returns the global debugger manager instance, or ``nil`` if the debugger is
+ not enabled.
+
+Methods
+^^^^^^^
+
+debugger:command(str)
+ Execute a debugger console command. The argument is the command string.
+ The output is sent to both the debugger console and the Lua console.
+
+Properties
+^^^^^^^^^^
+
+debugger.consolelog[] (read-only)
+ The lines in the console log (output from debugger commands). This
+ container only supports index and length operations.
+debugger.errorlog[] (read-only)
+ The lines in the error log (``logerror`` output). This container only
+ supports index and length operations.
+debugger.visible_cpu (read/write)
+ The CPU device with debugger focus. Changes become visible in the debugger
+ console after the next step. Setting to a device that is not a CPU has no
+ effect.
+debugger.execution_state (read/write)
+ Either ``"run"`` if the emulated system is running, or ``"stop"`` if it is
+ stopped in the debugger.
+
+.. _luareference-debug-devdebug:
+
+Device debugger interface
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Wraps MAME’s ``device_debug`` class, providing the debugger interface to an
+emulated CPU device.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag]:debug()
+ Returns the debugger interface for an emulated CPU device, or ``nil`` if the
+ device is not a CPU.
+
+Methods
+^^^^^^^
+
+debug:step([cnt])
+ Step by the specified number of instructions. If the instruction count is
+ not provided, it defaults to a single instruction.
+debug:go()
+ Run the emulated CPU.
+debug:bpset(addr, [cond], [act])
+ Set a breakpoint at the specified address, with an optional condition and
+ action. If the action is not specified, it defaults to just breaking into
+ the debugger. Returns the breakpoint number for the new breakpoint.
+
+ If specified, the condition must be a debugger expression that will be
+ evaluated each time the breakpoint is hit. Execution will only be stopped
+ if the expression evaluates to a non-zero value. If the condition is not
+ specified, it defaults to always active.
+debug:bpenable([bp])
+ Enable the specified breakpoint, or all breakpoints for the device if no
+ breakpoint number is specified. Returns whether the specified number
+ matched a breakpoint if a breakpoint number is specified, or ``nil`` if no
+ breakpoint number is specified.
+debug:bpdisable([bp])
+ Disable the specified breakpoint, or all breakpoints for the device if no
+ breakpoint number is specified. Returns whether the specified number
+ matched a breakpoint if a breakpoint number is specified, or ``nil`` if no
+ breakpoint number is specified.
+debug:bpclear([bp])
+ Clear the specified breakpoint, or all breakpoints for the device if no
+ breakpoint number is specified. Returns whether the specified number
+ matched a breakpoint if a breakpoint number is specified, or ``nil`` if no
+ breakpoint number is specified.
+debug:bplist()
+ Returns a table of breakpoints for the device. The keys are the breakpoint
+ numbers, and the values are
+ :ref:`breakpoint objects <luareference-debug-breakpoint>`.
+debug:wpset(space, type, addr, len, [cond], [act])
+ Set a watchpoint over the specified address range, with an optional
+ condition and action. The type must be ``"r"``, ``"w"`` or ``"rw"`` for a
+ read, write or read/write breakpoint. If the action is not specified, it
+ defaults to just breaking into the debugger. Returns the watchpoint number
+ for the new watchpoint.
+
+ If specified, the condition must be a debugger expression that will be
+ evaluated each time the breakpoint is hit. Execution will only be stopped
+ if the expression evaluates to a non-zero value. For all watchpoints, a
+ ``wpaddr`` variable is set to the address that triggered the watchpoint.
+ When a watchpoint is triggered by a write, a ``wpdata`` variable is set to
+ the data being written. If the condition is not specified, it defaults to
+ always active.
+debug:wpenable([wp])
+ Enable the specified watchpoint, or all watchpoints for the device if no
+ watchpoint number is specified. Returns whether the specified number
+ matched a watchpoint if a watchpoint number is specified, or ``nil`` if no
+ watchpoint number is specified.
+debug:wpdisable([wp])
+ Disable the specified watchpoint, or all watchpoints for the device if no
+ watchpoint number is specified. Returns whether the specified number
+ matched a watchpoint if a watchpoint number is specified, or ``nil`` if no
+ watchpoint number is specified.
+debug:wpclear([wp])
+ Clear the specified watchpoint, or all watchpoints for the device if no
+ watchpoint number is specified. Returns whether the specified number
+ matched a watchpoint if a watchpoint number is specified, or ``nil`` if no
+ watchpoint number is specified.
+debug:wplist(space)
+ Returns a table of watchpoints for the specified address space of the
+ device. The keys are the watchpoint numbers, and the values are
+ :ref:`watchpoint objects <luareference-debug-watchpoint>`.
+
+.. _luareference-debug-breakpoint:
+
+Breakpoint
+~~~~~~~~~~
+
+Wraps MAME’s ``debug_breakpoint`` class, representing a breakpoint for an
+emulated CPU device.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag]:debug():bplist()[bp]
+ Gets the specified breakpoint for an emulated CPU device, or ``nil`` if no
+ breakpoint corresponds to the specified index.
+
+Properties
+^^^^^^^^^^
+
+breakpoint.index (read-only)
+ The breakpoint’s index. The can be used to enable, disable or clear the
+ breakpoint via the
+ :ref:`CPU debugger interface <luareference-debug-devdebug>`.
+breakpoint.enabled (read-only)
+ A Boolean indicating whether the breakpoint is currently enabled.
+breakpoint.address (read-only)
+ The breakpoint’s address.
+breakpoint.condition (read-only)
+ A debugger expression evaluated each time the breakpoint is hit. The action
+ will only be triggered if this expression evaluates to a non-zero value. An
+ empty string if no condition was specified.
+breakpoint.action (read-only)
+ An action the debugger will run when the breakpoint is hit and the condition
+ evaluates to a non-zero value. An empty string if no action was specified.
+
+.. _luareference-debug-watchpoint:
+
+Watchpoint
+~~~~~~~~~~
+
+Wraps MAME’s ``debug_watchpoint`` class, representing a watchpoint for an
+emulated CPU device.
+
+Instantiation
+^^^^^^^^^^^^^
+
+manager:machine().devices[tag]:debug():wplist(space)[wp]
+ Gets the specified watchpoint for an address space of an emulated CPU
+ device, or ``nil`` if no watchpoint in the address space corresponds to the
+ specified index.
+
+Properties
+^^^^^^^^^^
+
+watchpoint.index (read-only)
+ The watchpoint’s index. The can be used to enable, disable or clear the
+ watchpoint via the
+ :ref:`CPU debugger interface <luareference-debug-devdebug>`.
+watchpoint.enabled (read-only)
+ A Boolean indicating whether the watchpoint is currently enabled.
+watchpoint.type (read-only)
+ Either ``"r"``, ``"w"`` or ``"rw"`` for a read, write or read/write
+ watchpoint.
+watchpoint.address (read-only)
+ The starting address of the watchpoint’s address range.
+watchpoint.length (read-only)
+ The length of the watchpoint’s address range.
+watchpoint.condition (read-only)
+ A debugger expression evaluated each time the watchpoint is hit. The action
+ will only be triggered if this expression evaluates to a non-zero value. An
+ empty string if no condition was specified.
+watchpoint.action (read-only)
+ An action the debugger will run when the watchpoint is hit and the condition
+ evaluates to a non-zero value. An empty string if no action was specified.
diff --git a/docs/source/techspecs/memory.rst b/docs/source/techspecs/memory.rst
index 65b4ad93cb1..76a79ef6d76 100644
--- a/docs/source/techspecs/memory.rst
+++ b/docs/source/techspecs/memory.rst
@@ -522,7 +522,7 @@ or banks.
(...).mirror(mask)
Duplicate the range on the addresses reachable by setting any of the 1
-bits present in mask. For instance, a range 0-0x1f with mask 0x300
+bits present in mask. For instance, a range 0-0x1f with mirror 0x300
will be present on 0-0x1f, 0x100-0x11f, 0x200-0x21f and 0x300-0x31f.
The addresses passed in to the handler stay in the 0-0x1f range, the
mirror bits are not seen by the handler.
diff --git a/plugins/autofire/autofire_menu.lua b/plugins/autofire/autofire_menu.lua
index 4744de1b2ac..b9fb89d5042 100644
--- a/plugins/autofire/autofire_menu.lua
+++ b/plugins/autofire/autofire_menu.lua
@@ -76,6 +76,7 @@ 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)
@@ -108,10 +109,10 @@ end
-- Borrowed from the cheat plugin
local function poll_for_hotkey()
local input = manager:machine():input()
- local poller = input:sequence_poller()
+ local poller = input:switch_sequence_poller()
manager:machine():popmessage(_('Press button for hotkey or wait to leave unchanged'))
manager:machine():video():frame_update(true)
- poller:start('switch')
+ poller:start()
local time = os.clock()
local clearmsg = true
while (not poller:poll()) and (poller.modified or (os.clock() < time + 1)) do
@@ -132,16 +133,16 @@ local function poll_for_hotkey()
end
local function handle_configure_menu(index, event)
- -- Input
if index == 1 then
+ -- Input
if event == 'select' then
table.insert(menu_stack, MENU_TYPES.BUTTON)
return true
else
return false
end
- -- Hotkey
elseif index == 2 then
+ -- Hotkey
if event == 'select' then
local keycode = poll_for_hotkey()
if keycode then
@@ -153,16 +154,16 @@ local function handle_configure_menu(index, event)
else
return false
end
- -- On frames
elseif index == 3 then
+ -- On frames
manager:machine():popmessage(_('Number of frames button will be pressed'))
if event == 'left' then
current_button.on_frames = current_button.on_frames - 1
elseif event == 'right' then
current_button.on_frames = current_button.on_frames + 1
end
- -- Off frames
elseif index == 4 then
+ -- Off frames
manager:machine():popmessage(_('Number of frames button will be released'))
if event == 'left' then
current_button.off_frames = current_button.off_frames - 1
diff --git a/plugins/cheat/init.lua b/plugins/cheat/init.lua
index 082864bb2fb..2acb377192f 100644
--- a/plugins/cheat/init.lua
+++ b/plugins/cheat/init.lua
@@ -605,15 +605,21 @@ function cheat.startplugin()
local menu = {}
if hotkeymenu then
menu[1] = {_("Select cheat to set hotkey"), "", "off"}
- menu[2] = {"---", "", "off"}
+ menu[2] = {_("Press UI Clear to clear hotkey"), "", "off"}
+ menu[3] = {"---", "", "off"}
hotkeylist = {}
- local function hkcbfunc(cheat)
+ local function hkcbfunc(cheat, event)
+ if event == "clear" then
+ cheat.hotkeys = nil
+ return
+ end
+
local input = manager:machine():input()
- local poller = input:sequence_poller()
- manager:machine():popmessage(_("Press button for hotkey or wait to clear"))
+ local poller = input:switch_sequence_poller()
+ manager:machine():popmessage(_("Press button for hotkey or wait to leave unchanged"))
manager:machine():video():frame_update(true)
- poller:start("switch")
+ poller:start()
local time = os.clock()
local clearmsg = true
while (not poller:poll()) and (poller.modified or (os.clock() < time + 1)) do
@@ -627,10 +633,8 @@ function cheat.startplugin()
manager:machine():video():frame_update(true)
end
end
- if poller.valid then
+ if poller.modified and poller.valid then
cheat.hotkeys = { pressed = false, keys = poller.sequence }
- else
- cheat.hotkeys = nil
end
if clearmsg then
manager:machine():popmessage()
@@ -641,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"), ""}
- hotkeylist[#hotkeylist + 1] = function() return hkcbfunc(cheat) end
+ hotkeylist[#hotkeylist + 1] = function(event) return hkcbfunc(cheat, event) end
end
end
menu[#menu + 1] = {"---", "", ""}
@@ -701,12 +705,12 @@ function cheat.startplugin()
local function menu_callback(index, event)
manager:machine():popmessage()
if hotkeymenu then
- if event == "select" then
- index = index - 2
+ if event == "select" or event == "clear" then
+ index = index - 3
if index >= 1 and index <= #hotkeylist then
- hotkeylist[index]()
+ hotkeylist[index](event)
return true
- elseif index == #hotkeylist + 2 then
+ elseif index == #hotkeylist + 2 and event == "select" then
hotkeymenu = false
return true
end
diff --git a/plugins/cheatfind/init.lua b/plugins/cheatfind/init.lua
index e540fe59fe6..1a3be72d9bc 100644
--- a/plugins/cheatfind/init.lua
+++ b/plugins/cheatfind/init.lua
@@ -302,9 +302,11 @@ function cheatfind.startplugin()
for tag, list in pairs(space_table) do
for name, space in pairs(list) do
local ram = {}
- for num, entry in pairs(space.map) do
- if entry.writetype == "ram" then
- ram[#ram + 1] = { offset = entry.offset, size = entry.endoff - entry.offset }
+ for num, entry in pairs(space.map.entries) do
+ if entry.write.handlertype == "ram" then
+ ram[#ram + 1] = {
+ offset = entry.address_start & space.address_mask,
+ size = (entry.address_end & space.address_mask) - (entry.address_start & space.address_mask) }
if space.shift > 0 then
ram[#ram].size = ram[#ram].size >> space.shift
elseif space.shift < 0 then
diff --git a/plugins/gdbstub/init.lua b/plugins/gdbstub/init.lua
index f2292bc0027..e850e62ae5b 100644
--- a/plugins/gdbstub/init.lua
+++ b/plugins/gdbstub/init.lua
@@ -175,7 +175,7 @@ function gdbstub.startplugin()
local data = ""
local space = cpu.spaces["program"]
for count = 1, len do
- data = data .. string.format("%.2x", space:read_log_u8(addr))
+ data = data .. string.format("%.2x", space:readv_u8(addr))
addr = addr + 1
end
socket:write("+$" .. data .. "#" .. chksum(data))
@@ -188,7 +188,7 @@ function gdbstub.startplugin()
if addr and len and data then
addr = tonumber(addr, 16)
local space = cpu.spaces["program"]
- data:gsub("%x%x", function(s) space:write_log_u8(addr + count, tonumber(s, 16)) count = count + 1 end)
+ data:gsub("%x%x", function(s) space:writev_u8(addr + count, tonumber(s, 16)) count = count + 1 end)
socket:write("+$OK#9a")
else
socket:write("+$E00#a5")
diff --git a/src/emu/input.cpp b/src/emu/input.cpp
index 36f6e3f5fe6..ffcdaf722be 100644
--- a/src/emu/input.cpp
+++ b/src/emu/input.cpp
@@ -672,7 +672,7 @@ bool input_manager::code_pressed_once(input_code code)
if (m_switch_memory[memnum] == code)
{
// if no longer pressed, clear entry
- if (curvalue == false)
+ if (!curvalue)
m_switch_memory[memnum] = INPUT_CODE_INVALID;
// always return false
@@ -684,11 +684,11 @@ bool input_manager::code_pressed_once(input_code code)
empty = memnum;
}
- // if we get here, we were not previously pressed; if still not pressed, return 0
- if (curvalue == false)
+ // if we get here, we were not previously pressed; if still not pressed, return false
+ if (!curvalue)
return false;
- // otherwise, add ourself to the memory and return 1
+ // otherwise, add the code to the memory and return true
assert(empty != -1);
if (empty != -1)
m_switch_memory[empty] = code;
@@ -697,196 +697,6 @@ bool input_manager::code_pressed_once(input_code code)
//-------------------------------------------------
-// reset_polling - reset memories in preparation
-// for polling
-//-------------------------------------------------
-
-void input_manager::reset_polling()
-{
- // reset switch memory
- reset_memory();
-
- // iterate over device classes and devices
- for (input_device_class devclass = DEVICE_CLASS_FIRST_VALID; devclass <= DEVICE_CLASS_LAST_VALID; ++devclass)
- for (int devnum = 0; devnum <= m_class[devclass]->maxindex(); devnum++)
- {
- // fetch the device; ignore if nullptr
- input_device *device = m_class[devclass]->device(devnum);
- if (device == nullptr)
- continue;
-
- // iterate over items within each device
- for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid)
- {
- // for any non-switch items, set memory equal to the current value
- input_device_item *item = device->item(itemid);
- if (item != nullptr && item->itemclass() != ITEM_CLASS_SWITCH)
- item->set_memory(code_value(item->code()));
- }
- }
-}
-
-
-//-------------------------------------------------
-// poll_switches - poll for any input
-//-------------------------------------------------
-
-input_code input_manager::poll_switches()
-{
- // iterate over device classes and devices
- for (input_device_class devclass = DEVICE_CLASS_FIRST_VALID; devclass <= DEVICE_CLASS_LAST_VALID; ++devclass)
- {
- // skip device class if disabled
- if (!m_class[devclass]->enabled())
- continue;
-
- for (int devnum = 0; devnum <= m_class[devclass]->maxindex(); devnum++)
- {
- // fetch the device; ignore if nullptr
- input_device *device = m_class[devclass]->device(devnum);
- if (device == nullptr)
- continue;
-
- // iterate over items within each device
- for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid)
- {
- input_device_item *item = device->item(itemid);
- if (item != nullptr)
- {
- input_code code = item->code();
-
- // if the item is natively a switch, poll it
- if (item->itemclass() == ITEM_CLASS_SWITCH)
- {
- if (code_pressed_once(code))
- return code;
- else
- continue;
- }
-
- // skip if there is not enough axis movement
- if (!item->check_axis(code.item_modifier()))
- continue;
-
- // otherwise, poll axes digitally
- code.set_item_class(ITEM_CLASS_SWITCH);
-
- // if this is a joystick X axis, check with left/right modifiers
- if (devclass == DEVICE_CLASS_JOYSTICK && code.item_id() == ITEM_ID_XAXIS)
- {
- code.set_item_modifier(ITEM_MODIFIER_LEFT);
- if (code_pressed_once(code))
- return code;
- code.set_item_modifier(ITEM_MODIFIER_RIGHT);
- if (code_pressed_once(code))
- return code;
- }
-
- // if this is a joystick Y axis, check with up/down modifiers
- else if (devclass == DEVICE_CLASS_JOYSTICK && code.item_id() == ITEM_ID_YAXIS)
- {
- code.set_item_modifier(ITEM_MODIFIER_UP);
- if (code_pressed_once(code))
- return code;
- code.set_item_modifier(ITEM_MODIFIER_DOWN);
- if (code_pressed_once(code))
- return code;
- }
-
- // any other axis, check with pos/neg modifiers
- else
- {
- code.set_item_modifier(ITEM_MODIFIER_POS);
- if (code_pressed_once(code))
- return code;
- code.set_item_modifier(ITEM_MODIFIER_NEG);
- if (code_pressed_once(code))
- return code;
- }
- }
- }
- }
- }
-
- // if nothing, return an invalid code
- return INPUT_CODE_INVALID;
-}
-
-
-//-------------------------------------------------
-// poll_keyboard_switches - poll for any
-// keyboard-specific input
-//-------------------------------------------------
-
-input_code input_manager::poll_keyboard_switches()
-{
- // iterate over devices within each class
- input_class &keyboard_class = device_class(DEVICE_CLASS_KEYBOARD);
- for (int devnum = 0; devnum < keyboard_class.maxindex(); devnum++)
- {
- // fetch the device; ignore if nullptr
- input_device *device = keyboard_class.device(devnum);
- if (device == nullptr)
- continue;
-
- // iterate over items within each device
- for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid)
- {
- input_device_item *item = device->item(itemid);
- if (item != nullptr && item->itemclass() == ITEM_CLASS_SWITCH)
- {
- input_code code = item->code();
- if (code_pressed_once(code))
- return code;
- }
- }
- }
-
- // if nothing, return an invalid code
- return INPUT_CODE_INVALID;
-}
-
-
-//-------------------------------------------------
-// poll_axes - poll for any input
-//-------------------------------------------------
-
-input_code input_manager::poll_axes()
-{
- // iterate over device classes and devices
- for (input_device_class devclass = DEVICE_CLASS_FIRST_VALID; devclass <= DEVICE_CLASS_LAST_VALID; ++devclass)
- {
- // skip device class if disabled
- if (!m_class[devclass]->enabled())
- continue;
-
- for (int devnum = 0; devnum <= m_class[devclass]->maxindex(); devnum++)
- {
- // fetch the device; ignore if nullptr
- input_device *device = m_class[devclass]->device(devnum);
- if (device == nullptr)
- continue;
-
- // iterate over items within each device
- for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid)
- {
- input_device_item *item = device->item(itemid);
- if (item != nullptr && item->itemclass() != ITEM_CLASS_SWITCH)
- {
- input_code code = item->code();
- if (item->check_axis(code.item_modifier()))
- return code;
- }
- }
- }
- }
-
- // if nothing, return an invalid code
- return INPUT_CODE_INVALID;
-}
-
-
-//-------------------------------------------------
// device_from_code - given an input_code return
// a pointer to the associated device
//-------------------------------------------------
diff --git a/src/emu/input.h b/src/emu/input.h
index b92bd7ce71f..6e8636e9956 100644
--- a/src/emu/input.h
+++ b/src/emu/input.h
@@ -379,6 +379,7 @@ public:
// operators
constexpr bool operator==(const input_code &rhs) const noexcept { return m_internal == rhs.m_internal; }
constexpr bool operator!=(const input_code &rhs) const noexcept { return m_internal != rhs.m_internal; }
+ constexpr bool operator<(const input_code &rhs) const noexcept { return m_internal < rhs.m_internal; }
// getters
constexpr bool internal() const noexcept { return device_class() == DEVICE_CLASS_INTERNAL; }
@@ -505,12 +506,6 @@ public:
bool code_pressed(input_code code) { return code_value(code) != 0; }
bool code_pressed_once(input_code code);
- // input code polling
- void reset_polling();
- input_code poll_axes();
- input_code poll_switches();
- input_code poll_keyboard_switches();
-
// input code helpers
input_device *device_from_code(input_code code) const;
input_device_item *item_from_code(input_code code) const;
diff --git a/src/frontend/mame/iptseqpoll.cpp b/src/frontend/mame/iptseqpoll.cpp
index 8082b257e2f..145c64f033a 100644
--- a/src/frontend/mame/iptseqpoll.cpp
+++ b/src/frontend/mame/iptseqpoll.cpp
@@ -1,113 +1,299 @@
// license:BSD-3-Clause
-// copyright-holders:Vas Crabb,Aaron Giles
+// copyright-holders:Vas Crabb, Aaron Giles
#include "emu.h"
#include "iptseqpoll.h"
+#include "inputdev.h"
+
#include <cassert>
+#include <algorithm>
-input_sequence_poller::input_sequence_poller(input_manager &manager) noexcept :
- m_manager(manager),
- m_sequence(),
- m_class(ITEM_CLASS_INVALID),
- m_last_ticks(0),
- m_modified(false)
+input_code_poller::input_code_poller(input_manager &manager) noexcept :
+ m_manager(manager)
{
}
-void input_sequence_poller::start(input_item_class itemclass)
+input_code_poller::~input_code_poller()
{
- m_sequence.reset();
- do_start(itemclass);
}
-void input_sequence_poller::start(input_item_class itemclass, input_seq const &startseq)
+void input_code_poller::reset()
{
- // grab the starting sequence to append to, and append an OR if it isn't empty
- m_sequence = startseq;
- if (input_seq::end_code != m_sequence[0])
- m_sequence += input_seq::or_code;
+ // iterate over device classes and devices
+ for (input_device_class classno = DEVICE_CLASS_FIRST_VALID; DEVICE_CLASS_LAST_VALID >= classno; ++classno)
+ {
+ input_class &devclass(m_manager.device_class(classno));
+ for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum)
+ {
+ // fetch the device; ignore if nullptr
+ input_device *const device(devclass.device(devnum));
+ if (device)
+ {
+ // iterate over items within each device
+ for (input_item_id itemid = ITEM_ID_FIRST_VALID; device->maxitem() >= itemid; ++itemid)
+ {
+ // for any non-switch items, set memory to the current value
+ input_device_item *const item(device->item(itemid));
+ if (item && (item->itemclass() != ITEM_CLASS_SWITCH))
+ item->set_memory(m_manager.code_value(item->code()));
+ }
+ }
+ }
+ }
+}
+
+
- do_start(itemclass);
+switch_code_poller_base::switch_code_poller_base(input_manager &manager) noexcept :
+ input_code_poller(manager),
+ m_switch_memory()
+{
}
-bool input_sequence_poller::poll()
+void switch_code_poller_base::reset()
{
- assert((ITEM_CLASS_SWITCH == m_class) || (ITEM_CLASS_ABSOLUTE == m_class) || (ITEM_CLASS_RELATIVE == m_class));
- int const curlen = m_sequence.length();
- input_code lastcode = m_sequence[curlen - 1];
+ m_switch_memory.clear();
+ input_code_poller::reset();
+}
+
+
+bool switch_code_poller_base::code_pressed_once(input_code code)
+{
+ // look for the code in the memory
+ bool const pressed(m_manager.code_pressed(code));
+ auto const found(std::lower_bound(m_switch_memory.begin(), m_switch_memory.end(), code));
+ if ((m_switch_memory.end() != found) && (*found == code))
+ {
+ // if no longer pressed, clear entry
+ if (!pressed)
+ m_switch_memory.erase(found);
+
+ // always return false
+ return false;
+ }
+
+ // if we get here, we were not previously pressed; if still not pressed, return false
+ if (!pressed)
+ return false;
+
+ // otherwise, add the code to the memory and return true
+ m_switch_memory.emplace(found, code);
+ return true;
+}
+
+
+
+axis_code_poller::axis_code_poller(input_manager &manager) noexcept :
+ input_code_poller(manager)
+{
+}
+
- input_code newcode;
- if (ITEM_CLASS_SWITCH == m_class)
+input_code axis_code_poller::poll()
+{
+ // iterate over device classes and devices, skipping disabled classes
+ for (input_device_class classno = DEVICE_CLASS_FIRST_VALID; DEVICE_CLASS_LAST_VALID >= classno; ++classno)
{
- // switch case: see if we have a new code to process
- newcode = m_manager.poll_switches();
- if (INPUT_CODE_INVALID != newcode)
+ input_class &devclass(m_manager.device_class(classno));
+ if (devclass.enabled())
{
- // if code is duplicate, toggle the NOT state on the code
- if (curlen && (newcode == lastcode))
+ for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum)
{
- // back up over the existing code
- m_sequence.backspace();
-
- // if there was a NOT preceding it, delete it as well, otherwise append a fresh one
- if (m_sequence[curlen - 2] == input_seq::not_code)
- m_sequence.backspace();
- else
- m_sequence += input_seq::not_code;
+ // fetch the device; ignore if nullptr
+ input_device *const device(devclass.device(devnum));
+ if (device)
+ {
+ // iterate over items within each device
+ for (input_item_id itemid = ITEM_ID_FIRST_VALID; device->maxitem() >= itemid; ++itemid)
+ {
+ input_device_item *const item(device->item(itemid));
+ if (item && (item->itemclass() != ITEM_CLASS_SWITCH))
+ {
+ input_code const code = item->code();
+ if (item->check_axis(code.item_modifier()))
+ return code;
+ }
+ }
+ }
}
}
}
- else
+
+ // if nothing, return an invalid code
+ return INPUT_CODE_INVALID;
+}
+
+
+
+switch_code_poller::switch_code_poller(input_manager &manager) noexcept :
+ switch_code_poller_base(manager)
+{
+}
+
+
+input_code switch_code_poller::poll()
+{
+ // iterate over device classes and devices, skipping disabled classes
+ for (input_device_class classno = DEVICE_CLASS_FIRST_VALID; DEVICE_CLASS_LAST_VALID >= classno; ++classno)
{
- // absolute/relative case: see if we have an analog change of sufficient amount
- bool const has_or = input_seq::or_code == lastcode;
- if (has_or)
- lastcode = m_sequence[curlen - 2];
- newcode = m_manager.poll_axes();
-
- // if the last code doesn't match absolute/relative of this code, ignore the new one
- input_item_class const lastclass = lastcode.item_class();
- input_item_class const newclass = newcode.item_class();
- if (((ITEM_CLASS_ABSOLUTE == lastclass) && (ITEM_CLASS_ABSOLUTE != newclass)) ||
- ((ITEM_CLASS_RELATIVE == lastclass) && (ITEM_CLASS_RELATIVE != newclass)))
- newcode = INPUT_CODE_INVALID;
-
- // if the new code is valid, check for half-axis toggles on absolute controls
- if ((INPUT_CODE_INVALID != newcode) && curlen && (ITEM_CLASS_ABSOLUTE == newclass))
+ input_class &devclass(m_manager.device_class(classno));
+ if (devclass.enabled())
{
- input_code last_nomodifier = lastcode;
- last_nomodifier.set_item_modifier(ITEM_MODIFIER_NONE);
- if (newcode == last_nomodifier)
+ for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum)
{
- // increment the modifier, wrapping back to none
- switch (lastcode.item_modifier())
+ // fetch the device; ignore if nullptr
+ input_device *const device(devclass.device(devnum));
+ if (device)
{
- case ITEM_MODIFIER_NONE:
- newcode.set_item_modifier(ITEM_MODIFIER_POS);
- break;
- case ITEM_MODIFIER_POS:
- newcode.set_item_modifier(ITEM_MODIFIER_NEG);
- break;
- default:
- case ITEM_MODIFIER_NEG:
- newcode.set_item_modifier(ITEM_MODIFIER_NONE);
- break;
+ // iterate over items within each device
+ for (input_item_id itemid = ITEM_ID_FIRST_VALID; device->maxitem() >= itemid; ++itemid)
+ {
+ input_device_item *const item(device->item(itemid));
+ if (item)
+ {
+ input_code code = item->code();
+ if (item->itemclass() == ITEM_CLASS_SWITCH)
+ {
+ // item is natively a switch, poll it
+ if (code_pressed_once(code))
+ return code;
+ }
+ else if (item->check_axis(code.item_modifier()))
+ {
+ // poll axes digitally
+ code.set_item_class(ITEM_CLASS_SWITCH);
+ if ((classno == DEVICE_CLASS_JOYSTICK) && (code.item_id() == ITEM_ID_XAXIS))
+ {
+ // joystick X axis - check with left/right modifiers
+ code.set_item_modifier(ITEM_MODIFIER_LEFT);
+ if (code_pressed_once(code))
+ return code;
+ code.set_item_modifier(ITEM_MODIFIER_RIGHT);
+ if (code_pressed_once(code))
+ return code;
+ }
+ else if ((classno == DEVICE_CLASS_JOYSTICK) && (code.item_id() == ITEM_ID_YAXIS))
+ {
+ // if this is a joystick Y axis, check with up/down modifiers
+ code.set_item_modifier(ITEM_MODIFIER_UP);
+ if (code_pressed_once(code))
+ return code;
+ code.set_item_modifier(ITEM_MODIFIER_DOWN);
+ if (code_pressed_once(code))
+ return code;
+ }
+ else
+ {
+ // any other axis, check with pos/neg modifiers
+ code.set_item_modifier(ITEM_MODIFIER_POS);
+ if (code_pressed_once(code))
+ return code;
+ code.set_item_modifier(ITEM_MODIFIER_NEG);
+ if (code_pressed_once(code))
+ return code;
+ }
+ }
+ }
+ }
}
+ }
+ }
+ }
- // back up over the previous code so we can re-append
- if (has_or)
- m_sequence.backspace();
- m_sequence.backspace();
+ // if nothing, return an invalid code
+ return INPUT_CODE_INVALID;
+}
+
+
+
+keyboard_code_poller::keyboard_code_poller(input_manager &manager) noexcept :
+ switch_code_poller_base(manager)
+{
+}
+
+
+input_code keyboard_code_poller::poll()
+{
+ // iterate over devices in keyboard class
+ input_class &devclass = m_manager.device_class(DEVICE_CLASS_KEYBOARD);
+ for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum)
+ {
+ // fetch the device; ignore if nullptr
+ input_device *const device(devclass.device(devnum));
+ if (device)
+ {
+ // iterate over items within each device
+ for (input_item_id itemid = ITEM_ID_FIRST_VALID; itemid <= device->maxitem(); ++itemid)
+ {
+ // iterate over items within each device
+ for (input_item_id itemid = ITEM_ID_FIRST_VALID; device->maxitem() >= itemid; ++itemid)
+ {
+ input_device_item *const item = device->item(itemid);
+ if (item && (item->itemclass() == ITEM_CLASS_SWITCH))
+ {
+ input_code const code = item->code();
+ if (code_pressed_once(code))
+ return code;
+ }
+ }
}
}
}
+ // if nothing, return an invalid code
+ return INPUT_CODE_INVALID;
+}
+
+
+
+input_sequence_poller::input_sequence_poller() noexcept :
+ m_sequence(),
+ m_last_ticks(0),
+ m_modified(false)
+{
+}
+
+
+input_sequence_poller::~input_sequence_poller()
+{
+}
+
+
+void input_sequence_poller::start()
+{
+ // start with an empty sequence
+ m_sequence.reset();
+
+ // reset the recording count and the clock
+ m_last_ticks = 0;
+ m_modified = false;
+ do_start();
+}
+
+
+void input_sequence_poller::start(input_seq const &startseq)
+{
+ // grab the starting sequence to append to, and append an OR if it isn't empty
+ m_sequence = startseq;
+ if (input_seq::end_code != m_sequence[0])
+ m_sequence += input_seq::or_code;
+
+ // reset the recording count and the clock
+ m_last_ticks = 0;
+ m_modified = false;
+ do_start();
+}
+
+
+bool input_sequence_poller::poll()
+{
// if we got a new code to append it, append it and reset the timer
+ input_code const newcode = do_poll();
osd_ticks_t const newticks = osd_ticks();
if (INPUT_CODE_INVALID != newcode)
{
@@ -118,27 +304,116 @@ bool input_sequence_poller::poll()
// if we're recorded at least one item and 2/3 of a second has passed, we're done
if (m_last_ticks && ((m_last_ticks + (osd_ticks_per_second() * 2 / 3)) < newticks))
- {
- m_class = ITEM_CLASS_INVALID;
return true;
- }
// return false to indicate we are still polling
return false;
}
-void input_sequence_poller::do_start(input_item_class itemclass)
+
+axis_sequence_poller::axis_sequence_poller(input_manager &manager) noexcept :
+ input_sequence_poller(),
+ m_code_poller(manager)
{
- assert((ITEM_CLASS_SWITCH == itemclass) || (ITEM_CLASS_ABSOLUTE == itemclass) || (ITEM_CLASS_RELATIVE == itemclass));
+}
- // reset the recording count and the clock
- m_class = itemclass;
- m_last_ticks = 0;
- m_modified = false;
+void axis_sequence_poller::do_start()
+{
// wait for any inputs that are already active to be released
- m_manager.reset_polling();
+ m_code_poller.reset();
for (input_code dummycode = KEYCODE_ENTER; INPUT_CODE_INVALID != dummycode; )
- dummycode = (ITEM_CLASS_SWITCH == itemclass) ? m_manager.poll_switches() : m_manager.poll_axes();
+ dummycode = m_code_poller.poll();
+}
+
+
+input_code axis_sequence_poller::do_poll()
+{
+ // absolute/relative case: see if we have an analog change of sufficient amount
+ int const curlen = m_sequence.length();
+ input_code lastcode = m_sequence[curlen - 1];
+ bool const has_or = input_seq::or_code == lastcode;
+ if (has_or)
+ lastcode = m_sequence[curlen - 2];
+ input_code newcode = m_code_poller.poll();
+
+ // if the last code doesn't match absolute/relative of this code, ignore the new one
+ input_item_class const lastclass = lastcode.item_class();
+ input_item_class const newclass = newcode.item_class();
+ if (((ITEM_CLASS_ABSOLUTE == lastclass) && (ITEM_CLASS_ABSOLUTE != newclass)) ||
+ ((ITEM_CLASS_RELATIVE == lastclass) && (ITEM_CLASS_RELATIVE != newclass)))
+ newcode = INPUT_CODE_INVALID;
+
+ // if the new code is valid, check for half-axis toggles on absolute controls
+ if ((INPUT_CODE_INVALID != newcode) && curlen && (ITEM_CLASS_ABSOLUTE == newclass))
+ {
+ input_code last_nomodifier = lastcode;
+ last_nomodifier.set_item_modifier(ITEM_MODIFIER_NONE);
+ if (newcode == last_nomodifier)
+ {
+ // increment the modifier, wrapping back to none
+ switch (lastcode.item_modifier())
+ {
+ case ITEM_MODIFIER_NONE:
+ newcode.set_item_modifier(ITEM_MODIFIER_POS);
+ break;
+ case ITEM_MODIFIER_POS:
+ newcode.set_item_modifier(ITEM_MODIFIER_NEG);
+ break;
+ default:
+ case ITEM_MODIFIER_NEG:
+ newcode.set_item_modifier(ITEM_MODIFIER_NONE);
+ break;
+ }
+
+ // back up over the previous code so we can re-append
+ if (has_or)
+ m_sequence.backspace();
+ m_sequence.backspace();
+ }
+ }
+ return newcode;
+}
+
+
+
+switch_sequence_poller::switch_sequence_poller(input_manager &manager) noexcept :
+ input_sequence_poller(),
+ m_code_poller(manager)
+{
+}
+
+
+void switch_sequence_poller::do_start()
+{
+ // wait for any inputs that are already active to be released
+ m_code_poller.reset();
+ for (input_code dummycode = KEYCODE_ENTER; INPUT_CODE_INVALID != dummycode; )
+ dummycode = m_code_poller.poll();
+}
+
+
+input_code switch_sequence_poller::do_poll()
+{
+ // switch case: see if we have a new code to process
+ int const curlen = m_sequence.length();
+ input_code lastcode = m_sequence[curlen - 1];
+ input_code newcode = m_code_poller.poll();
+ if (INPUT_CODE_INVALID != newcode)
+ {
+ // if code is duplicate, toggle the NOT state on the code
+ if (curlen && (newcode == lastcode))
+ {
+ // back up over the existing code
+ m_sequence.backspace();
+
+ // if there was a NOT preceding it, delete it as well, otherwise append a fresh one
+ if (m_sequence[curlen - 2] == input_seq::not_code)
+ m_sequence.backspace();
+ else
+ m_sequence += input_seq::not_code;
+ }
+ }
+ return newcode;
}
diff --git a/src/frontend/mame/iptseqpoll.h b/src/frontend/mame/iptseqpoll.h
index e3083f7509a..13c0d9c6484 100644
--- a/src/frontend/mame/iptseqpoll.h
+++ b/src/frontend/mame/iptseqpoll.h
@@ -12,28 +12,116 @@
#pragma once
+#include <vector>
+
+
+class input_code_poller
+{
+public:
+ virtual ~input_code_poller();
+
+ virtual void reset();
+ virtual input_code poll() = 0;
+
+protected:
+ input_code_poller(input_manager &manager) noexcept;
+
+ input_manager &m_manager;
+};
+
+
+class switch_code_poller_base : public input_code_poller
+{
+public:
+ virtual void reset() override;
+
+protected:
+ switch_code_poller_base(input_manager &manager) noexcept;
+
+ bool code_pressed_once(input_code code);
+
+private:
+ std::vector<input_code> m_switch_memory;
+};
+
+
+class axis_code_poller : public input_code_poller
+{
+public:
+ axis_code_poller(input_manager &manager) noexcept;
+
+ virtual input_code poll() override;
+};
+
+
+class switch_code_poller : public switch_code_poller_base
+{
+public:
+ switch_code_poller(input_manager &manager) noexcept;
+
+ virtual input_code poll() override;
+};
+
+
+class keyboard_code_poller : public switch_code_poller_base
+{
+public:
+ keyboard_code_poller(input_manager &manager) noexcept;
+
+ virtual input_code poll() override;
+};
+
class input_sequence_poller
{
public:
- input_sequence_poller(input_manager &manager) noexcept;
+ virtual ~input_sequence_poller();
- void start(input_item_class itemclass);
- void start(input_item_class itemclass, input_seq const &startseq);
+ void start();
+ void start(input_seq const &startseq);
bool poll();
input_seq const &sequence() const noexcept { return m_sequence; }
bool valid() const noexcept { return m_sequence.is_valid(); }
bool modified() const noexcept { return m_modified; }
-private:
- void do_start(input_item_class itemclass);
+protected:
+ input_sequence_poller() noexcept;
- input_manager &m_manager;
input_seq m_sequence;
- input_item_class m_class;
+
+private:
+ virtual void do_start() = 0;
+ virtual input_code do_poll() = 0;
+
osd_ticks_t m_last_ticks;
bool m_modified;
};
+
+class axis_sequence_poller : public input_sequence_poller
+{
+public:
+ axis_sequence_poller(input_manager &manager) noexcept;
+
+private:
+ virtual void do_start() override;
+ virtual input_code do_poll() override;
+
+ axis_code_poller m_code_poller;
+};
+
+
+class switch_sequence_poller : public input_sequence_poller
+{
+public:
+ switch_sequence_poller(input_manager &manager) noexcept;
+
+private:
+ virtual void do_start() override;
+ virtual input_code do_poll() override;
+
+ switch_code_poller m_code_poller;
+};
+
#endif // MAME_FRONTEND_IPTSEQPOLL_H
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 45e6367bdfc..4e7fb5412da 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -299,50 +299,6 @@ bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler
return sol::stack::check<int>(L, index, std::forward<Handler>(handler));
}
-int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value)
-{
- const char *typestr;
- switch(value)
- {
- case AMH_NONE:
- typestr = "none";
- break;
- case AMH_RAM:
- typestr = "ram";
- break;
- case AMH_ROM:
- typestr = "rom";
- break;
- case AMH_NOP:
- typestr = "nop";
- break;
- case AMH_UNMAP:
- typestr = "unmap";
- break;
- case AMH_DEVICE_DELEGATE:
- case AMH_DEVICE_DELEGATE_M:
- case AMH_DEVICE_DELEGATE_S:
- case AMH_DEVICE_DELEGATE_SM:
- case AMH_DEVICE_DELEGATE_MO:
- case AMH_DEVICE_DELEGATE_SMO:
- typestr = "delegate";
- break;
- case AMH_PORT:
- typestr = "port";
- break;
- case AMH_BANK:
- typestr = "bank";
- break;
- case AMH_DEVICE_SUBMAP:
- typestr = "submap";
- break;
- default:
- typestr = "unknown";
- break;
- }
- return sol::stack::push(L, typestr);
-}
-
//-------------------------------------------------
// process_snapshot_filename - processes a snapshot
diff --git a/src/frontend/mame/luaengine.ipp b/src/frontend/mame/luaengine.ipp
index 3c878b68c2a..d6ca0e981a0 100644
--- a/src/frontend/mame/luaengine.ipp
+++ b/src/frontend/mame/luaengine.ipp
@@ -268,6 +268,9 @@ bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler
// map_handler_type customisation
int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value);
+// endianness customisation
+int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value);
+
template <typename T>
struct lua_engine::immutable_container_helper
diff --git a/src/frontend/mame/luaengine_debug.cpp b/src/frontend/mame/luaengine_debug.cpp
index aec17ada89b..7297a7f82a3 100644
--- a/src/frontend/mame/luaengine_debug.cpp
+++ b/src/frontend/mame/luaengine_debug.cpp
@@ -93,18 +93,6 @@ void lua_engine::initialize_debug(sol::table &emu)
};
-/* debugger_manager library (requires debugger to be active)
- *
- * manager:machine():debugger()
- *
- * debugger:command(command_string) - run command_string in debugger console
- *
- * debugger.consolelog[] - get consolelog text buffer (wrap_textbuf)
- * debugger.errorlog[] - get errorlog text buffer (wrap_textbuf)
- * debugger.visible_cpu - accessor for debugger active cpu for commands, affects debug views
- * debugger.execution_state - accessor for active cpu run state
- */
-
auto debugger_type = sol().registry().new_usertype<debugger_manager>("debugger", sol::no_constructor);
debugger_type["command"] = [] (debugger_manager &debug, std::string const &cmd) { debug.console().execute_command(cmd, false); };
debugger_type["consolelog"] = sol::property([] (debugger_manager &debug) { return wrap_textbuf(debug.console().get_console_textbuf()); });
@@ -116,7 +104,7 @@ void lua_engine::initialize_debug(sol::table &emu)
[] (debugger_manager &debug) { return debug.cpu().is_stopped() ? "stop" : "run"; },
[] (debugger_manager &debug, std::string const &state)
{
- if(state == "stop")
+ if (state == "stop")
debug.cpu().set_execution_stopped();
else
debug.cpu().set_execution_running();
@@ -139,27 +127,6 @@ void lua_engine::initialize_debug(sol::table &emu)
"__len", [](wrap_textbuf &buf) { return text_buffer_num_lines(buf.textbuf) + text_buffer_line_index_to_seqnum(buf.textbuf, 0) - 1; });
-/* device_debug library (requires debugger to be active)
- *
- * manager:machine().devices[device_tag]:debug()
- *
- * debug:step([opt] steps) - run cpu steps, default 1
- * debug:go() - run cpu
- * debug:bpset(addr, [opt] cond, [opt] act) - set breakpoint on addr, cond and act are debugger
- * expressions. returns breakpoint index
- * debug:bpclr(idx) - clear breakpoint
- * debug:bpenable(idx) - enable breakpoint
- * debug:bpdisable(idx) - disable breakpoint
- * debug:bplist()[] - table of breakpoints (k=index, v=debug_breakpoint)
- * debug:wpset(space, type, addr, len, [opt] cond, [opt] act) - set watchpoint, cond and act
- * are debugger expressions.
- * returns watchpoint index
- * debug:wpclr(idx) - clear watchpoint
- * debug:wpenable(idx) - enable watchpoint
- * debug:wpdisable(idx) - disable watchpoint
- * debug:wplist(space)[] - table of watchpoints (k=index, v=debug_watchpoint)
- */
-
auto device_debug_type = sol().registry().new_usertype<device_debug>("device_debug", sol::no_constructor);
device_debug_type["step"] =
[] (device_debug &dev, sol::object num)
@@ -178,32 +145,23 @@ void lua_engine::initialize_debug(sol::table &emu)
dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS);
return result;
};
- device_debug_type["bpclear"] =
- [this] (device_debug &dev, sol::object index) -> sol::object
- {
- if (index == sol::lua_nil)
- {
- dev.breakpoint_clear_all();
- dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY);
- dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS);
- return sol::lua_nil;
- }
- else if (index.is<int>())
+ device_debug_type["bpclear"] = sol::overload(
+ [] (device_debug &dev, int index)
{
- bool result(dev.breakpoint_clear(index.as<int>()));
+ bool result(dev.breakpoint_clear(index));
if (result)
{
dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY);
dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS);
}
- return sol::make_object(sol(), result);
- }
- else
+ return result;
+ },
+ [] (device_debug &dev)
{
- osd_printf_error("[LUA ERROR] must call bpclear with integer or nil");
- return sol::lua_nil;
- }
- };
+ dev.breakpoint_clear_all();
+ dev.device().machine().debug_view().update_all(DVT_DISASSEMBLY);
+ dev.device().machine().debug_view().update_all(DVT_BREAK_POINTS);
+ });
device_debug_type["bpenable"] = [this] (device_debug &dev, sol::object index) { return do_breakpoint_enable(sol(), dev, index, true); };
device_debug_type["bpdisable"] = [this] (device_debug &dev, sol::object index) { return do_breakpoint_enable(sol(), dev, index, false); };
device_debug_type["bplist"] =
@@ -222,28 +180,19 @@ void lua_engine::initialize_debug(sol::table &emu)
dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS);
return result;
};
- device_debug_type["wpclear"] =
- [this] (device_debug &dev, sol::object index) -> sol::object
- {
- if (index == sol::lua_nil)
- {
- dev.watchpoint_clear_all();
- dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS);
- return sol::lua_nil;
- }
- else if (index.is<int>())
+ device_debug_type["wpclear"] = sol::overload(
+ [] (device_debug &dev, int index)
{
- bool result(dev.watchpoint_clear(index.as<int>()));
+ bool result(dev.watchpoint_clear(index));
if (result)
dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS);
- return sol::make_object(sol(), result);
- }
- else
+ return result;
+ },
+ [] (device_debug &dev)
{
- osd_printf_error("[LUA ERROR] must call wpclear with integer or nil");
- return sol::lua_nil;
- }
- };
+ dev.watchpoint_clear_all();
+ dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS);
+ });
device_debug_type["wpenable"] = [this] (device_debug &dev, sol::object index) { return do_watchpoint_enable(sol(), dev, index, true); };
device_debug_type["wpdisable"] = [this] (device_debug &dev, sol::object index) { return do_watchpoint_enable(sol(), dev, index, false); };
device_debug_type["wplist"] =
@@ -256,17 +205,6 @@ void lua_engine::initialize_debug(sol::table &emu)
};
-/* debug_breakpoint library (requires debugger to be active)
- *
- * manager:machine().devices[device_tag]:debug():bplist()[index]
- *
- * breakpoint.index - stable index of breakpoint
- * breakpoint.enabled - whether breakpoint is enabled
- * breakpoint.address -
- * breakpoint.condition -
- * breakpoint.action -
- */
-
auto breakpoint_type = sol().registry().new_usertype<debug_breakpoint>("breakpoint", sol::no_constructor);
breakpoint_type["index"] = sol::property(&debug_breakpoint::index);
breakpoint_type["enabled"] = sol::property(&debug_breakpoint::enabled);
@@ -275,19 +213,6 @@ void lua_engine::initialize_debug(sol::table &emu)
breakpoint_type["action"] = sol::property(&debug_breakpoint::action);
-/* debug_watchpoint library (requires debugger to be active)
- *
- * manager:machine().devices[device_tag]:debug():wplist()[index]
- *
- * watchpoint.index - stable index of watchpoint
- * watchpoint.enabled - whether breakpoint is enabled
- * watchpoint.type - type of access to watch ("r", "w" or "rw")
- * watchpoint.address - start of address range to watch
- * watchpoint.length - lenght of address range to watch
- * watchpoint.condition -
- * watchpoint.action -
- */
-
auto watchpoint_type = sol().registry().new_usertype<debug_watchpoint>("watchpoint", sol::no_constructor);
watchpoint_type["index"] = sol::property(&debug_watchpoint::index);
watchpoint_type["enabled"] = sol::property(&debug_watchpoint::enabled);
diff --git a/src/frontend/mame/luaengine_input.cpp b/src/frontend/mame/luaengine_input.cpp
index 77e002ce848..866117a29b2 100644
--- a/src/frontend/mame/luaengine_input.cpp
+++ b/src/frontend/mame/luaengine_input.cpp
@@ -140,43 +140,19 @@ void lua_engine::initialize_input(sol::table &emu)
};
-/* ioport_manager library
- *
- * manager:machine():ioport()
- *
- * ioport:count_players() - get count of player controllers
- * ioport:type_group(type, player)
- * ioport:type_seq(type, player, seqtype) - get input sequence for ioport type/player
- *
- * ioport.ports[] - ioports table (k=tag, v=ioport_port)
- * ioport.natkeyboard - get natural keyboard manager
- */
-
auto ioport_manager_type = sol().registry().new_usertype<ioport_manager>("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::type_seq;
+ ioport_manager_type["type_seq"] =
+ [this] (ioport_manager &im, ioport_type type, int player, std::string 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_type["ports"] = sol::property([] (ioport_manager &im) { return tag_object_ptr_map<ioport_list>(im.ports()); });
ioport_manager_type["natkeyboard"] = sol::property(&ioport_manager::natkeyboard);
-/* natural_keyboard library
- *
- * manager:machine():ioport().natkeyboard
- *
- * natkeyboard:post(text) - post data to natural keyboard
- * natkeyboard:post_coded(text) - post data to natural keyboard
- * natkeyboard:paste() - paste host clipboard text
- * natkeyboard:dump() - returns human-readable description of character mappings
- *
- * natkeyboard.empty - is the natural keyboard buffer empty?
- * natkeyboard.full - is the natural keyboard buffer full?
- * natkeyboard.can_post - does the system support posting characters via natural keyboard?
- * natkeyboard.is_posting - is a post operation currently in progress?
- * natkeyboard.in_use - is natural keyboard mode enabled (read/write)?
- * natkeyboard.keyboards[] - get keyboard devices in system (k=tag, v=natkbd_kbd_dev)
- */
-
auto natkeyboard_type = sol().registry().new_usertype<natural_keyboard>("natkeyboard", sol::no_constructor);
natkeyboard_type["post"] = [] (natural_keyboard &nat, std::string const &text) { nat.post_utf8(text); };
natkeyboard_type["post_coded"] = [] (natural_keyboard &nat, std::string const &text) { nat.post_coded(text); };
@@ -190,19 +166,6 @@ void lua_engine::initialize_input(sol::table &emu)
natkeyboard_type["keyboards"] = sol::property([] (natural_keyboard &nat) { return natkbd_kbd_list(nat); });
-/* natkbd_kbd_dev library
- *
- * manager:machine():ioport().natkeyboard.keyboards[tag]
- *
- * keyboard.device - underlying device that the inputs belong to
- * keyboard.tag - absolute tag of the device
- * keyboard.basetag - last component of the device tag ("root" for root device)
- * keyboard.name - device type full name
- * keyboard.shortname - device type short name
- * keyboard.is_keypad - does the device have keypad inputs but no keyboard inputs?
- * keyboard.enabled - are the device's keyboard/keypad inputs enabled (read/write)?
- */
-
auto natkbddev_type = sol().registry().new_usertype<natkbd_kbd_dev>("natkeyboard_device", sol::no_constructor);
natkbddev_type["device"] = sol::property([] (natkbd_kbd_dev const &kbd) -> device_t & { return kbd.manager.keyboard_device(kbd.index); });
natkbddev_type["tag"] = sol::property([] (natkbd_kbd_dev const &kbd) { return kbd.manager.keyboard_device(kbd.index).tag(); });
@@ -221,21 +184,6 @@ void lua_engine::initialize_input(sol::table &emu)
});
-/* ioport_port library
- *
- * manager:machine():ioport().ports[port_tag]
- *
- * port:read() - get port value
- * port:write(val, mask) - set port to value & mask (output fields only, for other fields use field:set_value(val))
- * port:field(mask) - get ioport_field for port and mask
- *
- * port.device - get device that the port belongs to
- * port.tag - get port tag
- * port.active - get port status
- * port.live - get port ioport_port_live (TODO: not usable from lua as of now)
- * port.fields[] - get ioport_field table (k=name, v=ioport_field)
- */
-
auto ioport_port_type = sol().registry().new_usertype<ioport_port>("ioport_port", "new", sol::no_constructor);
ioport_port_type["read"] = &ioport_port::read;
ioport_port_type["write"] = &ioport_port::write;
@@ -268,48 +216,6 @@ void lua_engine::initialize_input(sol::table &emu)
});
-/* ioport_field library
- *
- * manager:machine():ioport().ports[port_tag].fields[field_name]
- *
- * field:set_value(value)
- * field:set_input_seq(seq_type, seq)
- * field:input_seq(seq_type)
- * field:set_default_input_seq(seq_type, seq)
- * field:default_input_seq(seq_type)
- * field:keyboard_codes(which)
- *
- * field.device - get associated device_t
- * field.port - get associated ioport_port
- * field.live - get ioport_field_live
- * field.name
- * field.default_name
- * field.player
- * field.mask
- * field.defvalue
- * field.sensitivity
- * field.way - amount of available directions
- * field.type_class
- * field.is_analog
- * field.is_digital_joystick
- * field.enabled
- * field.optional
- * field.cocktail
- * field.toggle - whether field is a toggle
- * field.rotated
- * field.analog_reverse
- * field.analog_reset
- * field.analog_wraps
- * field.analog_invert
- * field.impulse
- * field.type
- * field.crosshair_scale
- * field.crosshair_offset
- * field.user_value
- *
- * field.settings[] - ioport_setting table (k=value, v=name)
- */
-
auto ioport_field_type = sol().registry().new_usertype<ioport_field>("ioport_field", sol::no_constructor);
ioport_field_type["set_value"] = &ioport_field::set_value;
ioport_field_type["set_input_seq"] =
@@ -350,6 +256,8 @@ void lua_engine::initialize_input(sol::table &emu)
};
ioport_field_type["device"] = sol::property(&ioport_field::device);
ioport_field_type["port"] = sol::property(&ioport_field::port);
+ ioport_field_type["live"] = sol::property(&ioport_field::live);
+ ioport_field_type["type"] = sol::property(&ioport_field::type);
ioport_field_type["name"] = sol::property(&ioport_field::name);
ioport_field_type["default_name"] = sol::property(
[] (ioport_field &f)
@@ -387,8 +295,6 @@ void lua_engine::initialize_input(sol::table &emu)
ioport_field_type["analog_wraps"] = sol::property(&ioport_field::analog_wraps);
ioport_field_type["analog_invert"] = sol::property(&ioport_field::analog_invert);
ioport_field_type["impulse"] = sol::property(&ioport_field::impulse);
- ioport_field_type["type"] = sol::property(&ioport_field::type);
- ioport_field_type["live"] = sol::property(&ioport_field::live);
ioport_field_type["crosshair_scale"] = sol::property(&ioport_field::crosshair_scale, &ioport_field::set_crosshair_scale);
ioport_field_type["crosshair_offset"] = sol::property(&ioport_field::crosshair_offset, &ioport_field::set_crosshair_offset);
ioport_field_type["user_value"] = sol::property(
@@ -416,37 +322,10 @@ void lua_engine::initialize_input(sol::table &emu)
});
-/* ioport_field_live library
- *
- * manager:machine():ioport().ports[port_tag].fields[field_name].live
- *
- * live.name
- */
-
auto ioport_field_live_type = sol().registry().new_usertype<ioport_field_live>("ioport_field_live", sol::no_constructor);
ioport_field_live_type["name"] = &ioport_field_live::name;
-/* input_manager library
- *
- * manager:machine():input()
- *
- * input:code_value(code) -
- * input:code_pressed(code) - get pressed state for input_code
- * input:code_pressed_once(code) -
- * input:code_name(code) - get code friendly name
- * input:code_to_token(code) - get KEYCODE_* string token for code
- * input:code_from_token(token) - get input_code for KEYCODE_* string token
- * input:seq_pressed(seq) - get pressed state for input_seq
- * input:seq_clean(seq) - clean the seq and remove invalid elements
- * input:seq_name(seq) - get seq friendly name
- * input:seq_to_tokens(seq) - get KEYCODE_* string tokens for seq
- * input:seq_from_tokens(tokens) - get input_seq for multiple space separated KEYCODE_* string tokens
- * input:sequence_poller() - get an input sequence poller
- *
- * input.device_classes[] - returns device classes (k=name, v=input_device_class)
- */
-
auto input_type = sol().registry().new_usertype<input_manager>("input", sol::no_constructor);
input_type["code_value"] = &input_manager::code_value;
input_type["code_pressed"] = &input_manager::code_pressed;
@@ -465,7 +344,11 @@ void lua_engine::initialize_input(sol::table &emu)
input.seq_from_tokens(seq, tokens);
return seq;
};
- input_type["sequence_poller"] = [] (input_manager &input) { return input_sequence_poller(input); };
+ input_type["axis_code_poller"] = [] (input_manager &input) { return std::unique_ptr<input_code_poller>(new axis_code_poller(input)); };
+ input_type["switch_code_poller"] = [] (input_manager &input) { return std::unique_ptr<input_code_poller>(new switch_code_poller(input)); };
+ input_type["keyboard_code_poller"] = [] (input_manager &input) { return std::unique_ptr<input_code_poller>(new keyboard_code_poller(input)); };
+ input_type["axis_sequence_poller"] = [] (input_manager &input) { return std::unique_ptr<input_sequence_poller>(new axis_sequence_poller(input)); };
+ input_type["switch_sequence_poller"] = [] (input_manager &input) { return std::unique_ptr<input_sequence_poller>(new switch_sequence_poller(input)); };
input_type["device_classes"] = sol::property(
[this] (input_manager &input)
{
@@ -479,60 +362,25 @@ void lua_engine::initialize_input(sol::table &emu)
});
-/* input_sequence_poller library
- *
- * manager:machine():input():seq_poll()
- *
- * poller:start(class, [opt] start_seq) - start polling for input_item_class passed as string
- * (switch/abs[olute]/rel[ative]/max[imum])
- * poller:poll() - poll once, returns true if input was fetched
- *
- * poller.sequence - get current input_seq
- * poller.valid - true if input sequence is valid
- * poller.modified - true if input sequence was modified
- */
+ auto codepoll_type = sol().registry().new_usertype<input_code_poller>("input_code_poller", sol::no_constructor);
+ codepoll_type["reset"] = &input_code_poller::reset;
+ codepoll_type["poll"] = &input_code_poller::poll;
+
auto seqpoll_type = sol().registry().new_usertype<input_sequence_poller>("input_seq_poller", sol::no_constructor);
- seqpoll_type["start"] =
- [] (input_sequence_poller &poller, char const *cls_string, sol::object seq)
- {
- input_item_class cls;
- if (!strcmp(cls_string, "switch"))
- cls = ITEM_CLASS_SWITCH;
- else if (!strcmp(cls_string, "absolute") || !strcmp(cls_string, "abs"))
- cls = ITEM_CLASS_ABSOLUTE;
- else if (!strcmp(cls_string, "relative") || !strcmp(cls_string, "rel"))
- cls = ITEM_CLASS_RELATIVE;
- else if (!strcmp(cls_string, "maximum") || !strcmp(cls_string, "max"))
- cls = ITEM_CLASS_MAXIMUM;
- else
- cls = ITEM_CLASS_INVALID;
-
- if (seq.is<sol::user<input_seq>>())
- poller.start(cls, seq.as<input_seq>());
- else
- poller.start(cls);
- };
+ seqpoll_type["start"] = sol::overload(
+ [] (input_sequence_poller &poller) { return poller.start(); },
+ [] (input_sequence_poller &poller, input_seq const &seq) { return poller.start(seq); });
seqpoll_type["poll"] = &input_sequence_poller::poll;
seqpoll_type["sequence"] = sol::property(&input_sequence_poller::sequence);
seqpoll_type["valid"] = sol::property(&input_sequence_poller::valid);
seqpoll_type["modified"] = sol::property(&input_sequence_poller::modified);
-/* input_class library
- *
- * manager:machine():input().device_classes[devclass]
- *
- * devclass.name
- * devclass.enabled
- * devclass.multi
- * devclass.devices[]
- */
-
- auto input_class_type = sol().registry().new_usertype<input_class>("input_class", "new", sol::no_constructor);
+ auto input_class_type = sol().registry().new_usertype<input_class>("input_class", sol::no_constructor);
input_class_type["name"] = sol::property(&input_class::name);
- input_class_type["enabled"] = sol::property(&input_class::enabled, &input_class::enable);
- input_class_type["multi"] = sol::property(&input_class::multi, &input_class::set_multi);
+ input_class_type["enabled"] = sol::property(&input_class::enabled);
+ input_class_type["multi"] = sol::property(&input_class::multi);
input_class_type["devices"] = sol::property(
[this] (input_class &devclass)
{
@@ -540,7 +388,7 @@ void lua_engine::initialize_input(sol::table &emu)
int index = 1;
for (int devindex = 0; devindex <= devclass.maxindex(); devindex++)
{
- input_device *dev = devclass.device(devindex);
+ input_device *const dev = devclass.device(devindex);
if (dev)
result[index++] = dev;
}
@@ -548,17 +396,7 @@ void lua_engine::initialize_input(sol::table &emu)
});
-/* input_device library
- *
- * manager:machine():input().device_classes[devclass].devices[index]
- *
- * device.name -
- * device.id -
- * device.devindex -
- * device.items[] -
- */
-
- auto input_device_type = sol().registry().new_usertype<input_device>("input_device", "new", sol::no_constructor);
+ auto input_device_type = sol().registry().new_usertype<input_device>("input_device", sol::no_constructor);
input_device_type["name"] = sol::property(&input_device::name);
input_device_type["id"] = sol::property(&input_device::id);
input_device_type["devindex"] = sol::property(&input_device::devindex);
@@ -576,40 +414,24 @@ void lua_engine::initialize_input(sol::table &emu)
});
-/* input_device_item library
- *
- * manager:machine():input().device_classes[devclass].devices[index].items[item_id]
- *
- * item.name -
- * item.code -
- * item.token -
- * item.current -
- */
-
- auto input_device_item_type = sol().registry().new_usertype<input_device_item>("input_device_item", "new", sol::no_constructor);
+ auto input_device_item_type = sol().registry().new_usertype<input_device_item>("input_device_item", sol::no_constructor);
input_device_item_type["name"] = sol::property(&input_device_item::name);
input_device_item_type["code"] = sol::property(&input_device_item::code);
input_device_item_type["token"] = sol::property(&input_device_item::token);
input_device_item_type["current"] = sol::property(&input_device_item::current);
-/* ui_input_manager library
- *
- * manager:machine():uiinput()
- *
- * uiinput:find_mouse() - return x, y, button state, ui render target
- * uiinput:pressed(key) - get pressed state for ui key
- * uiinput.presses_enabled - enable/disable ui key presses
- */
-
- auto uiinput_type = sol().registry().new_usertype<ui_input_manager>("uiinput", "new", sol::no_constructor);
- uiinput_type.set("find_mouse", [](ui_input_manager &ui) {
+ auto uiinput_type = sol().registry().new_usertype<ui_input_manager>("uiinput", sol::no_constructor);
+ uiinput_type["find_mouse"] =
+ [] (ui_input_manager &ui)
+ {
int32_t x, y;
bool button;
render_target *rt = ui.find_mouse(&x, &y, &button);
- return std::tuple<int32_t, int32_t, bool, render_target *>(x, y, button, rt);
- });
- uiinput_type.set("pressed", &ui_input_manager::pressed);
- uiinput_type.set("presses_enabled", sol::property(&ui_input_manager::presses_enabled, &ui_input_manager::set_presses_enabled));
+ 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["presses_enabled"] = sol::property(&ui_input_manager::presses_enabled, &ui_input_manager::set_presses_enabled);
}
diff --git a/src/frontend/mame/luaengine_mem.cpp b/src/frontend/mame/luaengine_mem.cpp
index dc9abcbbb21..4016ce1d20f 100644
--- a/src/frontend/mame/luaengine_mem.cpp
+++ b/src/frontend/mame/luaengine_mem.cpp
@@ -14,24 +14,6 @@
namespace {
-
-template <typename T>
-std::string get_endianness_name(T const &obj)
-{
- std::string endianness;
- switch (obj.endianness())
- {
- case endianness_t::ENDIANNESS_BIG:
- endianness = "big";
- break;
- case endianness_t::ENDIANNESS_LITTLE:
- endianness = "little";
- break;
- }
- return endianness;
-}
-
-
//-------------------------------------------------
// region_read - templated region readers for <sign>,<size>
// -> manager:machine():memory().regions[":maincpu"]:read_i8(0xC000)
@@ -141,6 +123,77 @@ void share_write(memory_share &share, offs_t address, T val)
//-------------------------------------------------
+// sol_lua_push - automatically convert
+// map_handler_type to a string
+//-------------------------------------------------
+
+int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value)
+{
+ const char *typestr;
+ switch(value)
+ {
+ case AMH_NONE:
+ typestr = "none";
+ break;
+ case AMH_RAM:
+ typestr = "ram";
+ break;
+ case AMH_ROM:
+ typestr = "rom";
+ break;
+ case AMH_NOP:
+ typestr = "nop";
+ break;
+ case AMH_UNMAP:
+ typestr = "unmap";
+ break;
+ case AMH_DEVICE_DELEGATE:
+ case AMH_DEVICE_DELEGATE_M:
+ case AMH_DEVICE_DELEGATE_S:
+ case AMH_DEVICE_DELEGATE_SM:
+ case AMH_DEVICE_DELEGATE_MO:
+ case AMH_DEVICE_DELEGATE_SMO:
+ typestr = "delegate";
+ break;
+ case AMH_PORT:
+ typestr = "port";
+ break;
+ case AMH_BANK:
+ typestr = "bank";
+ break;
+ case AMH_DEVICE_SUBMAP:
+ typestr = "submap";
+ break;
+ default:
+ typestr = "unknown";
+ break;
+ }
+ return sol::stack::push(L, typestr);
+}
+
+
+//-------------------------------------------------
+// sol_lua_push - automatically convert
+// endianness_t to a string
+//-------------------------------------------------
+
+int sol_lua_push(sol::types<endianness_t>, lua_State *L, endianness_t &&value)
+{
+ char const *endianness = "unknown";
+ switch (value)
+ {
+ case endianness_t::ENDIANNESS_BIG:
+ endianness = "big";
+ break;
+ case endianness_t::ENDIANNESS_LITTLE:
+ endianness = "little";
+ break;
+ }
+ return sol::stack::push(L, endianness);
+}
+
+
+//-------------------------------------------------
// mem_read - templated memory readers for <sign>,<size>
// -> manager:machine().devices[":maincpu"].spaces["program"]:read_i8(0xC000)
//-------------------------------------------------
@@ -356,36 +409,7 @@ void lua_engine::addr_space::direct_mem_write(offs_t address, T val)
void lua_engine::initialize_memory(sol::table &emu)
{
-/* addr_space library
- *
- * manager:machine().devices[device_tag].spaces[space]
- *
- * read/write by signedness u/i and bit-width 8/16/32/64:
- * space:read_*(addr)
- * space:write_*(addr, val)
- * space:read_log_*(addr)
- * space:write_log_*(addr, val)
- * space:read_direct_*(addr)
- * space:write_direct_*(addr, val)
- * space:read_range(first_addr, last_addr, width, [opt] step) - read range of addresses and
- * return as a binary string
- *
- * space.name - address space name
- * space.shift - address bus shift, bitshift required for a bytewise address
- * to map onto this space's address resolution (addressing granularity).
- * positive value means leftshift, negative means rightshift.
- * space.index
- * space.address_mask
- * space.data_width
- * space.endianness
- *
- * space.map[] - table of address map entries (k=index, v=address_map_entry)
- */
-
- auto addr_space_type = sol().registry().new_usertype<addr_space>(
- "addr_space",
- sol::call_constructor,
- sol::constructors<sol::types<address_space &, device_memory_interface &>>());
+ auto addr_space_type = sol().registry().new_usertype<addr_space>("addr_space", sol::no_constructor);
addr_space_type["read_i8"] = &addr_space::mem_read<s8>;
addr_space_type["read_u8"] = &addr_space::mem_read<u8>;
addr_space_type["read_i16"] = &addr_space::mem_read<s16>;
@@ -402,22 +426,22 @@ void lua_engine::initialize_memory(sol::table &emu)
addr_space_type["write_u32"] = &addr_space::mem_write<u32>;
addr_space_type["write_i64"] = &addr_space::mem_write<s64>;
addr_space_type["write_u64"] = &addr_space::mem_write<u64>;
- addr_space_type["read_log_i8"] = &addr_space::log_mem_read<s8>;
- addr_space_type["read_log_u8"] = &addr_space::log_mem_read<u8>;
- addr_space_type["read_log_i16"] = &addr_space::log_mem_read<s16>;
- addr_space_type["read_log_u16"] = &addr_space::log_mem_read<u16>;
- addr_space_type["read_log_i32"] = &addr_space::log_mem_read<s32>;
- addr_space_type["read_log_u32"] = &addr_space::log_mem_read<u32>;
- addr_space_type["read_log_i64"] = &addr_space::log_mem_read<s64>;
- addr_space_type["read_log_u64"] = &addr_space::log_mem_read<u64>;
- addr_space_type["write_log_i8"] = &addr_space::log_mem_write<s8>;
- addr_space_type["write_log_u8"] = &addr_space::log_mem_write<u8>;
- addr_space_type["write_log_i16"] = &addr_space::log_mem_write<s16>;
- addr_space_type["write_log_u16"] = &addr_space::log_mem_write<u16>;
- addr_space_type["write_log_i32"] = &addr_space::log_mem_write<s32>;
- addr_space_type["write_log_u32"] = &addr_space::log_mem_write<u32>;
- addr_space_type["write_log_i64"] = &addr_space::log_mem_write<s64>;
- addr_space_type["write_log_u64"] = &addr_space::log_mem_write<u64>;
+ addr_space_type["readv_i8"] = &addr_space::log_mem_read<s8>;
+ addr_space_type["readv_u8"] = &addr_space::log_mem_read<u8>;
+ addr_space_type["readv_i16"] = &addr_space::log_mem_read<s16>;
+ addr_space_type["readv_u16"] = &addr_space::log_mem_read<u16>;
+ addr_space_type["readv_i32"] = &addr_space::log_mem_read<s32>;
+ addr_space_type["readv_u32"] = &addr_space::log_mem_read<u32>;
+ addr_space_type["readv_i64"] = &addr_space::log_mem_read<s64>;
+ addr_space_type["readv_u64"] = &addr_space::log_mem_read<u64>;
+ addr_space_type["writev_i8"] = &addr_space::log_mem_write<s8>;
+ addr_space_type["writev_u8"] = &addr_space::log_mem_write<u8>;
+ addr_space_type["writev_i16"] = &addr_space::log_mem_write<s16>;
+ addr_space_type["writev_u16"] = &addr_space::log_mem_write<u16>;
+ addr_space_type["writev_i32"] = &addr_space::log_mem_write<s32>;
+ addr_space_type["writev_u32"] = &addr_space::log_mem_write<u32>;
+ addr_space_type["writev_i64"] = &addr_space::log_mem_write<s64>;
+ addr_space_type["writev_u64"] = &addr_space::log_mem_write<u64>;
addr_space_type["read_direct_i8"] = &addr_space::direct_mem_read<s8>;
addr_space_type["read_direct_u8"] = &addr_space::direct_mem_read<u8>;
addr_space_type["read_direct_i16"] = &addr_space::direct_mem_read<s16>;
@@ -435,7 +459,7 @@ void lua_engine::initialize_memory(sol::table &emu)
addr_space_type["write_direct_i64"] = &addr_space::direct_mem_write<s64>;
addr_space_type["write_direct_u64"] = &addr_space::direct_mem_write<u64>;
addr_space_type["read_range"] =
- [] (addr_space &sp, sol::this_state s, u64 first, u64 last, int width, sol::object opt_step)
+ [] (addr_space &sp, sol::this_state s, u64 first, u64 last, int width, sol::object opt_step) -> sol::object
{
lua_State *L = s;
luaL_Buffer buff;
@@ -447,13 +471,13 @@ void lua_engine::initialize_memory(sol::table &emu)
if (step < 1 || step > last - first)
{
luaL_error(L, "Invalid step");
- return sol::make_reference(L, nullptr);
+ return sol::lua_nil;
}
}
if (first > space_size || last > space_size || last < first)
{
luaL_error(L, "Invalid offset");
- return sol::make_reference(L, nullptr);
+ return sol::lua_nil;
}
int byte_count = width / 8 * (last - first + 1) / step;
switch (width)
@@ -488,7 +512,7 @@ void lua_engine::initialize_memory(sol::table &emu)
}
default:
luaL_error(L, "Invalid width. Must be 8/16/32/64");
- return sol::make_reference(L, nullptr);
+ return sol::lua_nil;
}
luaL_pushresultsize(&buff, byte_count);
return sol::make_reference(L, sol::stack_reference(L, -1));
@@ -498,44 +522,38 @@ void lua_engine::initialize_memory(sol::table &emu)
addr_space_type["index"] = sol::property([] (addr_space &sp) { return sp.space.spacenum(); });
addr_space_type["address_mask"] = sol::property([] (addr_space &sp) { return sp.space.addrmask(); });
addr_space_type["data_width"] = sol::property([] (addr_space &sp) { return sp.space.data_width(); });
- addr_space_type["endianness"] = sol::property([] (addr_space &sp) { return get_endianness_name(sp.space); });
-
-
-/* address_map_entry library
- *
- * manager:machine().devices[device_tag].spaces[space].map[entry_index]
- *
- * mapentry.offset - address start
- * mapentry.endoff - address end
- * mapentry.readtype
- * mapentry.writetype
- */
- addr_space_type["map"] = sol::property(
- [this] (addr_space &sp)
- {
- address_space &space = sp.space;
- sol::table map = sol().create_table();
- for (address_map_entry &entry : space.map()->m_entrylist)
- {
- sol::table mapentry = sol().create_table();
- mapentry["offset"] = entry.m_addrstart & space.addrmask();
- mapentry["endoff"] = entry.m_addrend & space.addrmask();
- mapentry["readtype"] = entry.m_read.m_type;
- mapentry["writetype"] = entry.m_write.m_type;
- map.add(mapentry);
- }
- return map;
- });
+ addr_space_type["endianness"] = sol::property([] (addr_space &sp) { return sp.space.endianness(); });
+ addr_space_type["map"] = sol::property([] (addr_space &sp) { return sp.space.map(); });
+
+ auto addrmap_type = sol().registry().new_usertype<address_map>("addrmap", sol::no_constructor);
+ addrmap_type["spacenum"] = sol::readonly(&address_map::m_spacenum);
+ addrmap_type["device"] = sol::readonly(&address_map::m_device);
+ addrmap_type["unmap_value"] = sol::readonly(&address_map::m_unmapval);
+ addrmap_type["global_mask"] = sol::readonly(&address_map::m_globalmask);
+ addrmap_type["entries"] = sol::property([] (address_map &m) { return simple_list_wrapper<address_map_entry>(m.m_entrylist); });
+
+
+ auto mapentry_type = sol().registry().new_usertype<address_map_entry>("mapentry", sol::no_constructor);
+ mapentry_type["address_start"] = sol::readonly(&address_map_entry::m_addrstart);
+ mapentry_type["address_end"] = sol::readonly(&address_map_entry::m_addrend);
+ mapentry_type["address_mirror"] = sol::readonly(&address_map_entry::m_addrmirror);
+ mapentry_type["address_mask"] = sol::readonly(&address_map_entry::m_addrmask);
+ mapentry_type["mask"] = sol::readonly(&address_map_entry::m_mask);
+ mapentry_type["cswidth"] = sol::readonly(&address_map_entry::m_cswidth);
+ mapentry_type["read"] = sol::readonly(&address_map_entry::m_read);
+ mapentry_type["write"] = sol::readonly(&address_map_entry::m_write);
+ mapentry_type["share"] = sol::readonly(&address_map_entry::m_share);
+ mapentry_type["region"] = sol::readonly(&address_map_entry::m_region);
+ mapentry_type["region_offset"] = sol::readonly(&address_map_entry::m_rgnoffs);
+
+
+ auto handler_data_type = sol().registry().new_usertype<map_handler_data>("handlerdata", sol::no_constructor);
+ handler_data_type["handlertype"] = sol::property([] (map_handler_data const &hd) { return hd.m_type; }); // can't use member pointer or won't be converted to string
+ handler_data_type["bits"] = sol::readonly(&map_handler_data::m_bits);
+ handler_data_type["name"] = sol::readonly(&map_handler_data::m_name);
+ handler_data_type["tag"] = sol::readonly(&map_handler_data::m_tag);
-/* memory_manager library
- *
- * manager:machine():memory()
- *
- * memory.banks[] - table of memory banks (k=tag, v=memory_bank)
- * memory.regions[] - table of memory regions (k=tag, v=memory_region)
- * memory.shares[] - table of memory shares (k=tag, v=memory_share)
- */
auto memory_type = sol().registry().new_usertype<memory_manager>("memory", sol::no_constructor);
memory_type["banks"] = sol::property([] (memory_manager &mm) { return standard_tag_object_ptr_map<memory_bank>(mm.banks()); });
@@ -543,35 +561,11 @@ void lua_engine::initialize_memory(sol::table &emu)
memory_type["shares"] = sol::property([] (memory_manager &mm) { return standard_tag_object_ptr_map<memory_share>(mm.shares()); });
-/* memory_bank library
- *
- * manager:machine():memory().banks[bank_tag]
- *
- * region.tag - absolute tag of the bank
- * bank.entry - get/set the selected entry
- */
-
auto bank_type = sol().registry().new_usertype<memory_bank>("membank", sol::no_constructor);
bank_type["tag"] = sol::property(&memory_bank::tag);
bank_type["entry"] = sol::property(&memory_bank::entry, &memory_bank::set_entry);
-/* memory_region library
- *
- * manager:machine():memory().regions[region_tag]
- *
- * read/write by signedness u/i and bit-width 8/16/32/64:
- * region:read_*(addr)
- * region:write_*(addr, val)
- *
- * region.tag - absolute tag of the region
- * region.size - size in bytes
- * region.length - length in items
- * region.endianness - endiannes as string ("big" or "little")
- * region.bitwidth - item width in bits
- * region.bytewidth - item width in bytes
- */
-
auto region_type = sol().registry().new_usertype<memory_region>("region", sol::no_constructor);
region_type["read_i8"] = &region_read<s8>;
region_type["read_u8"] = &region_read<u8>;
@@ -592,27 +586,11 @@ void lua_engine::initialize_memory(sol::table &emu)
region_type["tag"] = sol::property(&memory_region::name);
region_type["size"] = sol::property(&memory_region::bytes);
region_type["length"] = sol::property([] (memory_region &r) { return r.bytes() / r.bytewidth(); });
- region_type["endianness"] = sol::property(&get_endianness_name<memory_region>);
+ region_type["endianness"] = sol::property(&memory_region::endianness);
region_type["bitwidth"] = sol::property(&memory_region::bitwidth);
region_type["bytewidth"] = sol::property(&memory_region::bytewidth);
-/* memory_share library
- *
- * manager:machine():memory().shares[share_tag]
- *
- * read/write by signedness u/i and bit-width 8/16/32/64:
- * share:read_*(addr)
- * share:write_*(addr, val)
- *
- * share.tag - absolute tag of the share
- * share.size - size in bytes
- * share.length - length in items
- * region.endianness - endiannes as string ("big" or "little")
- * share.bitwidth - item width in bits
- * share.bytewidth - item width in bytes
-*/
-
auto share_type = sol().registry().new_usertype<memory_share>("share", sol::no_constructor);
share_type["read_i8"] = &share_read<s8>;
share_type["read_u8"] = &share_read<u8>;
@@ -633,7 +611,7 @@ void lua_engine::initialize_memory(sol::table &emu)
share_type["tag"] = sol::property(&memory_share::name);
share_type["size"] = sol::property(&memory_share::bytes);
share_type["length"] = sol::property([] (memory_share &s) { return s.bytes() / s.bytewidth(); });
- share_type["endianness"] = sol::property(&get_endianness_name<memory_share>);
+ share_type["endianness"] = sol::property(&memory_share::endianness);
share_type["bitwidth"] = sol::property(&memory_share::bitwidth);
share_type["bytewidth"] = sol::property(&memory_share::bytewidth);
diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp
index 0d49fc1ad29..94643849893 100644
--- a/src/frontend/mame/ui/inputmap.cpp
+++ b/src/frontend/mame/ui/inputmap.cpp
@@ -240,7 +240,7 @@ menu_input::menu_input(mame_ui_manager &mui, render_container &container)
: menu(mui, container)
, data()
, pollingitem(nullptr)
- , seq_poll(machine().input())
+ , seq_poll()
, errormsg()
, erroritem(nullptr)
, lastitem(nullptr)
@@ -269,7 +269,7 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float
{
if (pollingitem)
{
- const std::string seqname = machine().input().seq_name(seq_poll.sequence());
+ const std::string seqname = machine().input().seq_name(seq_poll->sequence());
char const *const text[] = { seqname.c_str() };
draw_text_box(
std::begin(text), std::end(text),
@@ -326,7 +326,7 @@ void menu_input::handle()
{
// if UI_CANCEL is pressed, abort
pollingitem = nullptr;
- if (!seq_poll.modified())
+ if (!seq_poll->modified())
{
// cancelled immediately - toggle between default and none
record_next = false;
@@ -338,14 +338,15 @@ void menu_input::handle()
// entered something before cancelling - abandon change
invalidate = true;
}
+ seq_poll.reset();
}
- else if (seq_poll.poll()) // poll again; if finished, update the sequence
+ else if (seq_poll->poll()) // poll again; if finished, update the sequence
{
pollingitem = nullptr;
- if (seq_poll.valid())
+ if (seq_poll->valid())
{
record_next = true;
- item->seq = seq_poll.sequence();
+ item->seq = seq_poll->sequence();
seqchangeditem = item;
}
else
@@ -355,6 +356,7 @@ void menu_input::handle()
errormsg = _("Invalid sequence entered");
erroritem = item;
}
+ seq_poll.reset();
}
}
else if (menu_event && menu_event->itemref)
@@ -369,10 +371,14 @@ void menu_input::handle()
pollingitem = &item;
lastitem = &item;
starting_seq = item.seq;
+ if (INPUT_TYPE_ANALOG == item.type)
+ seq_poll.reset(new axis_sequence_poller(machine().input()));
+ else
+ seq_poll.reset(new switch_sequence_poller(machine().input()));
if (record_next)
- seq_poll.start((item.type == INPUT_TYPE_ANALOG) ? ITEM_CLASS_ABSOLUTE : ITEM_CLASS_SWITCH, item.seq);
+ seq_poll->start(item.seq);
else
- seq_poll.start((item.type == INPUT_TYPE_ANALOG) ? ITEM_CLASS_ABSOLUTE : ITEM_CLASS_SWITCH);
+ seq_poll->start();
invalidate = true;
break;
diff --git a/src/frontend/mame/ui/inputmap.h b/src/frontend/mame/ui/inputmap.h
index 01649b0b1ef..bdc1449c89b 100644
--- a/src/frontend/mame/ui/inputmap.h
+++ b/src/frontend/mame/ui/inputmap.h
@@ -70,7 +70,7 @@ protected:
input_item_data *pollingitem;
private:
- input_sequence_poller seq_poll;
+ std::unique_ptr<input_sequence_poller> seq_poll;
std::string errormsg;
input_item_data *erroritem;
input_item_data *lastitem;
diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp
index 2fb36393ba7..90522bc48ae 100644
--- a/src/frontend/mame/ui/pluginopt.cpp
+++ b/src/frontend/mame/ui/pluginopt.cpp
@@ -18,6 +18,7 @@
namespace ui {
+
void menu_plugin::handle()
{
const event *menu_event = process(0);
diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp
index 3064fd654dd..81c210cced2 100644
--- a/src/frontend/mame/ui/state.cpp
+++ b/src/frontend/mame/ui/state.cpp
@@ -84,6 +84,7 @@ menu_load_save_state_base::file_entry::file_entry(std::string &&file_name, std::
menu_load_save_state_base::menu_load_save_state_base(mame_ui_manager &mui, render_container &container, std::string_view header, std::string_view footer, bool must_exist)
: menu(mui, container)
+ , m_switch_poller(machine().input())
, m_header(header)
, m_footer(footer)
, m_must_exist(must_exist)
@@ -224,7 +225,7 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom)
machine().pause();
// get ready to poll inputs
- machine().input().reset_polling();
+ m_switch_poller.reset();
m_keys_released = false;
}
@@ -279,7 +280,7 @@ std::string menu_load_save_state_base::get_visible_name(const std::string &file_
std::string menu_load_save_state_base::poll_inputs()
{
- input_code const code = machine().input().poll_switches();
+ input_code const code = m_switch_poller.poll();
if (INPUT_CODE_INVALID == code)
{
m_keys_released = true;
diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h
index 30bd9513bf3..cdf597db7d1 100644
--- a/src/frontend/mame/ui/state.h
+++ b/src/frontend/mame/ui/state.h
@@ -14,9 +14,12 @@
#include "ui/menu.h"
+#include "iptseqpoll.h"
+
#include <chrono>
#include <unordered_map>
+
namespace ui {
// ======================> menu_load_save_state_base
@@ -54,6 +57,7 @@ private:
static std::string s_last_file_selected;
+ switch_code_poller m_switch_poller;
std::unordered_map<std::string, file_entry> m_file_entries;
std::unordered_map<std::string, std::string> m_filename_to_code_map;
std::string_view const m_header;
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index 5918d0e13d6..1273c5e92df 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -11,8 +11,9 @@
#include "emu.h"
#include "ui/ui.h"
-#include "luaengine.h"
#include "infoxml.h"
+#include "iptseqpoll.h"
+#include "luaengine.h"
#include "mame.h"
#include "ui/filemngr.h"
#include "ui/info.h"
@@ -110,7 +111,6 @@ static input_item_id const non_char_keys[] =
// messagebox buffer
std::string mame_ui_manager::messagebox_text;
std::string mame_ui_manager::messagebox_poptext;
-rgb_t mame_ui_manager::messagebox_backcolor;
// slider info
std::vector<ui::menu_item> mame_ui_manager::slider_list;
@@ -203,8 +203,13 @@ void mame_ui_manager::init()
update_target_font_height();
// more initialization
- using namespace std::placeholders;
- set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_messagebox, this, _1));
+ set_handler(
+ ui_callback_type::GENERAL,
+ [this] (render_container &container) -> uint32_t
+ {
+ draw_text_box(container, messagebox_text, ui::text_layout::LEFT, 0.5f, 0.5f, colors().background_color());
+ return 0;
+ });
m_non_char_keys_down = std::make_unique<uint8_t[]>((ARRAY_LENGTH(non_char_keys) + 7) / 8);
m_mouse_show = machine().system().flags & machine_flags::CLICKABLE_ARTWORK ? true : false;
@@ -406,31 +411,56 @@ void mame_ui_manager::display_startup_screens(bool first_time)
show_gameinfo = show_warnings = false;
#endif
- // loop over states
+ // set up event handlers
using namespace std::placeholders;
+ switch_code_poller poller(machine().input());
+ std::string warning_text;
+ rgb_t warning_color;
+ auto handler_messagebox_anykey =
+ [this, &poller, &warning_text, &warning_color] (render_container &container) -> uint32_t
+ {
+ // draw a standard message window
+ draw_text_box(container, warning_text, ui::text_layout::LEFT, 0.5f, 0.5f, warning_color);
+
+ if (machine().ui_input().pressed(IPT_UI_CANCEL))
+ {
+ // if the user cancels, exit out completely
+ machine().schedule_exit();
+ return UI_HANDLER_CANCEL;
+ }
+ else if (poller.poll() != INPUT_CODE_INVALID)
+ {
+ // if any key is pressed, just exit
+ return UI_HANDLER_CANCEL;
+ }
+
+ return 0;
+ };
set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_ingame, this, _1));
+
+ // loop over states
for (int state = 0; state < maxstate && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(machine()); state++)
{
// default to standard colors
- messagebox_backcolor = colors().background_color();
- messagebox_text.clear();
+ warning_color = colors().background_color();
+ warning_text.clear();
// pick the next state
switch (state)
{
case 0:
if (show_gameinfo)
- messagebox_text = machine_info().game_info_string();
- if (!messagebox_text.empty())
+ warning_text = machine_info().game_info_string();
+ if (!warning_text.empty())
{
- messagebox_text.append(_("\n\nPress any key to continue"));
- set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
+ warning_text.append(_("\n\nPress any key to continue"));
+ set_handler(ui_callback_type::MODAL, handler_messagebox_anykey);
}
break;
case 1:
- messagebox_text = machine_info().warnings_string();
- m_has_warnings = !messagebox_text.empty();
+ warning_text = machine_info().warnings_string();
+ m_has_warnings = !warning_text.empty();
if (show_warnings)
{
bool need_warning = m_has_warnings;
@@ -496,9 +526,9 @@ void mame_ui_manager::display_startup_screens(bool first_time)
}
if (need_warning)
{
- messagebox_text.append(_("\n\nPress any key to continue"));
- set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
- messagebox_backcolor = machine_info().warnings_color();
+ warning_text.append(_("\n\nPress any key to continue"));
+ set_handler(ui_callback_type::MODAL, handler_messagebox_anykey);
+ warning_color = machine_info().warnings_color();
}
}
break;
@@ -519,15 +549,13 @@ void mame_ui_manager::display_startup_screens(bool first_time)
break;
}
- // clear the input memory
- machine().input().reset_polling();
- while (machine().input().poll_switches() != INPUT_CODE_INVALID) { }
+ // clear the input memory and wait for all keys to be released
+ poller.reset();
+ while (poller.poll() != INPUT_CODE_INVALID) { }
// loop while we have a handler
while (m_handler_callback_type == ui_callback_type::MODAL && !machine().scheduled_event_pending() && !ui::menu::stack_has_special_main_menu(machine()))
- {
machine().video().frame_update();
- }
// clear the handler and force an update
set_handler(ui_callback_type::GENERAL, std::bind(&mame_ui_manager::handler_ingame, this, _1));
@@ -556,7 +584,6 @@ void mame_ui_manager::set_startup_text(const char *text, bool force)
// copy in the new text
messagebox_text.assign(text);
- messagebox_backcolor = colors().background_color();
// don't update more than 4 times/second
if (force || (curtime - lastupdatetime) > osd_ticks_per_second() / 4)
@@ -598,7 +625,7 @@ void mame_ui_manager::update_and_render(render_container &container)
// display any popup messages
if (osd_ticks() < m_popup_text_end)
- draw_text_box(container, messagebox_poptext, ui::text_layout::CENTER, 0.5f, 0.9f, messagebox_backcolor);
+ draw_text_box(container, messagebox_poptext, ui::text_layout::CENTER, 0.5f, 0.9f, colors().background_color());
else
m_popup_text_end = 0;
@@ -947,46 +974,6 @@ bool mame_ui_manager::is_menu_active(void)
***************************************************************************/
//-------------------------------------------------
-// handler_messagebox - displays the current
-// messagebox_text string but handles no input
-//-------------------------------------------------
-
-uint32_t mame_ui_manager::handler_messagebox(render_container &container)
-{
- draw_text_box(container, messagebox_text, ui::text_layout::LEFT, 0.5f, 0.5f, messagebox_backcolor);
- return 0;
-}
-
-
-//-------------------------------------------------
-// handler_messagebox_anykey - displays the
-// current messagebox_text string and waits for
-// any keypress
-//-------------------------------------------------
-
-uint32_t mame_ui_manager::handler_messagebox_anykey(render_container &container)
-{
- uint32_t state = 0;
-
- // draw a standard message window
- draw_text_box(container, messagebox_text, ui::text_layout::LEFT, 0.5f, 0.5f, messagebox_backcolor);
-
- // if the user cancels, exit out completely
- if (machine().ui_input().pressed(IPT_UI_CANCEL))
- {
- machine().schedule_exit();
- state = UI_HANDLER_CANCEL;
- }
-
- // if any key is pressed, just exit
- else if (machine().input().poll_switches() != INPUT_CODE_INVALID)
- state = UI_HANDLER_CANCEL;
-
- return state;
-}
-
-
-//-------------------------------------------------
// process_natural_keyboard - processes any
// natural keyboard input
//-------------------------------------------------
@@ -2232,7 +2219,6 @@ void mame_ui_manager::popup_time_string(int seconds, std::string message)
{
// extract the text
messagebox_poptext = message;
- messagebox_backcolor = colors().background_color();
// set a timer
m_popup_text_end = osd_ticks() + osd_ticks_per_second() * seconds;
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index d2fcd19d512..932957d9f9d 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -299,14 +299,11 @@ private:
// static variables
static std::string messagebox_text;
static std::string messagebox_poptext;
- static rgb_t messagebox_backcolor;
static std::vector<ui::menu_item> slider_list;
static slider_state *slider_current;
// UI handlers
- uint32_t handler_messagebox(render_container &container);
- uint32_t handler_messagebox_anykey(render_container &container);
uint32_t handler_ingame(render_container &container);
uint32_t handler_load_save(render_container &container, uint32_t state);
uint32_t handler_confirm_quit(render_container &container);
diff --git a/src/mame/drivers/goldnpkr.cpp b/src/mame/drivers/goldnpkr.cpp
index 5d62be8fda9..e331c4e5630 100644
--- a/src/mame/drivers/goldnpkr.cpp
+++ b/src/mame/drivers/goldnpkr.cpp
@@ -1869,20 +1869,20 @@ static INPUT_PORTS_START( goldnpkr )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Off (Payout)") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_NAME("Off (Payout)")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -1940,8 +1940,8 @@ static INPUT_PORTS_START( pmpoker )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -1950,11 +1950,11 @@ static INPUT_PORTS_START( pmpoker )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Take Score (Kasse)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) PORT_NAME("Hold 2 / Small (Tief)")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) PORT_NAME("Hold 3 / Bet (Setze)")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) PORT_NAME("Hold 4 / Big (Hoch)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Double Up (Dopp.)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Take Score (Kasse)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) PORT_NAME("Hold 2 / Small (Tief)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) PORT_NAME("Hold 3 / Bet (Setze)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) PORT_NAME("Hold 4 / Big (Hoch)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Double Up (Dopp.)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -2000,20 +2000,20 @@ static INPUT_PORTS_START( pottnpkr )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -2070,21 +2070,21 @@ INPUT_PORTS_END
static INPUT_PORTS_START( potnpkra )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin 1")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -2139,21 +2139,21 @@ INPUT_PORTS_END
static INPUT_PORTS_START( animpkr )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin 1 + Start")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin 1 + Start")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("IN0-0 80") PORT_CODE(KEYCODE_G)
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
@@ -2210,24 +2210,24 @@ static INPUT_PORTS_START( potnpkrc )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
-static INPUT_PORTS_START( ngold)
+static INPUT_PORTS_START( ngold )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -2281,75 +2281,13 @@ static INPUT_PORTS_START( ngold)
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
-static INPUT_PORTS_START( ngoldb) // only coinage changes against ngold...
+static INPUT_PORTS_START( ngoldb ) // only coinage changes against ngold...
// Multiplexed - 4x5bits
- PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("IN0-2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2 )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3 )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4 )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_INCLUDE( ngold )
- PORT_START("IN0-3")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Settings") PORT_CODE(KEYCODE_F2)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_MODIFY("IN0-3")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(3) PORT_NAME("Note In")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin In)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
- PORT_START("SW1")
- // only bits 4-7 are connected here and were routed to SW1 1-4
- PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x00, "Minimal Hand" ) PORT_DIPLOCATION("SW1:1")
- PORT_DIPSETTING( 0x00, "Pair of Aces" )
- PORT_DIPSETTING( 0x10, "Double Pair" )
- PORT_DIPNAME( 0x20, 0x00, "50hz/60hz" ) PORT_DIPLOCATION("SW1:2")
- PORT_DIPSETTING( 0x20, "50hz" )
- PORT_DIPSETTING( 0x00, "60hz" )
- // listed in the manual as "Play Mode"
- PORT_DIPNAME( 0x40, 0x00, "Payout Mode" ) PORT_DIPLOCATION("SW1:3")
- PORT_DIPSETTING( 0x40, "Manual" ) // listed in the manual as "Out Play"
- PORT_DIPSETTING( 0x00, "Auto" ) // listed in the manual as "Credit Play"
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:4")
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
static INPUT_PORTS_START( goodluck )
@@ -2357,8 +2295,8 @@ static INPUT_PORTS_START( goodluck )
PORT_INCLUDE( goldnpkr )
PORT_MODIFY("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_MODIFY("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Settings") PORT_CODE(KEYCODE_F2)
@@ -2408,8 +2346,8 @@ static INPUT_PORTS_START( witchcrd )
PORT_INCLUDE( goldnpkr )
PORT_MODIFY("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON13 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON14 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_MODIFY("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Settings") PORT_CODE(KEYCODE_F2)
@@ -2484,21 +2422,21 @@ INPUT_PORTS_END
static INPUT_PORTS_START( witchcda )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Apuesta (Bet)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Contabilidad (Bookkeeping)")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Doblar (Double Up)")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Reparte (Deal)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL ) PORT_NAME("Cancela (Cancel)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Apuesta (Bet)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Contabilidad (Bookkeeping)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Doblar (Double Up)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Reparte (Deal)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL ) PORT_NAME("Cancela (Cancel)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Pagar (Payout)") PORT_CODE(KEYCODE_W)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Cobrar (Take)")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Alta (Big)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Baja (Small)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_NAME("Pagar (Payout)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Cobrar (Take)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Alta (Big)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Baja (Small)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -2626,8 +2564,8 @@ static INPUT_PORTS_START( witchcdd )
PORT_INCLUDE( witchcrd )
PORT_MODIFY("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON13 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON14 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("IN0-1-6")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("IN0-1-7")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("IN0-1-8")
@@ -2700,8 +2638,8 @@ static INPUT_PORTS_START( witchjol )
PORT_INCLUDE( witchcrd )
PORT_MODIFY("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON13 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON14 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("IN0-1-6")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("IN0-1-7")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("IN0-1-8")
@@ -2793,8 +2731,8 @@ static INPUT_PORTS_START( witchcdf )
PORT_INCLUDE( witchcrd )
PORT_MODIFY("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON13 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON14 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("IN0-1-6")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("IN0-1-7")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("IN0-1-8")
@@ -2863,31 +2801,31 @@ INPUT_PORTS_END
static INPUT_PORTS_START( wldwitch )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON13 ) PORT_IMPULSE(3) PORT_NAME("Manual Collect") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON14 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Manual Collect")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Take")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Take")
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4 )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Double-Up")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Double-Up")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3002,10 +2940,10 @@ INPUT_PORTS_END
static INPUT_PORTS_START( wupndown )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3013,7 +2951,7 @@ static INPUT_PORTS_START( wupndown )
PORT_START("IN0-1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3034,7 +2972,7 @@ static INPUT_PORTS_START( wupndown )
PORT_START("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Service") PORT_CODE(KEYCODE_F2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Note In")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Note In")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin 1 In")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(3) PORT_NAME("Coin 2 In")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3097,10 +3035,10 @@ INPUT_PORTS_END
static INPUT_PORTS_START( wstrike )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3109,7 +3047,7 @@ static INPUT_PORTS_START( wstrike )
PORT_START("IN0-1")
// PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("IN1-1")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
@@ -3131,9 +3069,9 @@ static INPUT_PORTS_START( wstrike )
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Service") PORT_CODE(KEYCODE_F2)
// PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("IN3-2")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Note In")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Note In")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin In")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Weight (Coupon In)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Weight (Coupon In)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3194,10 +3132,10 @@ INPUT_PORTS_END
static INPUT_PORTS_START( wtchjack )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet (Setzen)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping / Test")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal (Geben)")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3205,7 +3143,7 @@ static INPUT_PORTS_START( wtchjack )
PORT_START("IN0-1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("IN1-1")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
@@ -3226,9 +3164,9 @@ static INPUT_PORTS_START( wtchjack )
PORT_START("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Service") PORT_CODE(KEYCODE_F2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("IN3-2")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Note In")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Note In")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin In")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Weight (Coupon In)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Weight (Coupon In)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3292,7 +3230,7 @@ static INPUT_PORTS_START( sloco93 )
PORT_MODIFY("IN0-1")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Negro (Black)") PORT_CODE(KEYCODE_A)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Rojo (Red)") PORT_CODE(KEYCODE_S)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Rojo (Red)") PORT_CODE(KEYCODE_S)
PORT_MODIFY("SW1")
// only bits 4-7 are connected here and were routed to SW1 1-4
@@ -3317,21 +3255,21 @@ INPUT_PORTS_END
static INPUT_PORTS_START( bsuerte )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Apostar (Bet)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Contabilidad (Meters)")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Doblar (Double Up)")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Dar/Virar (Deal/Draw)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL ) PORT_NAME("Cancelar (Cancel)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Apostar (Bet)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Contabilidad (Meters)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Doblar (Double Up)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Dar/Virar (Deal/Draw)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL ) PORT_NAME("Cancelar (Cancel)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Pagar (Payout)") PORT_CODE(KEYCODE_W)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Cobrar (Take)")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Mayor (Big)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Menor (Small)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_NAME("Pagar (Payout)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Cobrar (Take)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Mayor (Big)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Menor (Small)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3349,9 +3287,9 @@ static INPUT_PORTS_START( bsuerte )
PORT_START("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Configuracion (Settings)") PORT_CODE(KEYCODE_F2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Billetes (Note In)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Billetes (Note In)")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Fichas (Coin In)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Cupones (Coupon In)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME("Cupones (Coupon In)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3419,7 +3357,7 @@ static INPUT_PORTS_START( poker91 )
PORT_MODIFY("IN0-1")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Negro (Black)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Rojo (Red)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Rojo (Red)")
PORT_MODIFY("IN0-2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Switch Card 1")
@@ -3449,10 +3387,10 @@ static INPUT_PORTS_START( wildcard )
PORT_START("IN0-1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("High/Red")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Low/Black")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("High/Red")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Low/Black")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3526,10 +3464,10 @@ INPUT_PORTS_END
static INPUT_PORTS_START( genie )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_CODE(KEYCODE_1)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Play")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Play")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3537,7 +3475,7 @@ static INPUT_PORTS_START( genie )
PORT_START("IN0-1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Collect") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Collect")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW )
@@ -3558,7 +3496,7 @@ static INPUT_PORTS_START( genie )
PORT_START("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Settings") PORT_CODE(KEYCODE_9)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Coupon (Note In)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Coupon (Note In)")
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3) PORT_NAME("Coin In")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3597,17 +3535,17 @@ static INPUT_PORTS_START( caspoker )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Bookkeeping")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("Payout") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3616,11 +3554,11 @@ static INPUT_PORTS_START( caspoker )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Take Score (Kasse)")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) PORT_NAME("Hold 2 / Small (Tief)")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) PORT_NAME("Hold 3 / Bet (Setzen)")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) PORT_NAME("Hold 4 / Big (Hoch)")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Double Up (Doppeln)")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_POKER_HOLD1 ) PORT_NAME("Hold 1 / Take Score (Kasse)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_POKER_HOLD2 ) PORT_NAME("Hold 2 / Small (Tief)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_POKER_HOLD3 ) PORT_NAME("Hold 3 / Bet (Setzen)")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_POKER_HOLD4 ) PORT_NAME("Hold 4 / Big (Hoch)")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_HOLD5 ) PORT_NAME("Hold 5 / Double Up (Doppeln)")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3675,11 +3613,11 @@ static INPUT_PORTS_START( mondial )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT )
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3745,21 +3683,21 @@ static INPUT_PORTS_START( videtron )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT )
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-2")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Card Selector") PORT_CODE(KEYCODE_Z)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Card Selector") PORT_CODE(KEYCODE_Z)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Hold Card") PORT_CODE(KEYCODE_X)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Hold Card") PORT_CODE(KEYCODE_X)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3768,9 +3706,9 @@ static INPUT_PORTS_START( videtron )
PORT_START("IN0-3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("Settings") PORT_CODE(KEYCODE_F2)
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(3)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3)
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_IMPULSE(3)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(3)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(3)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_IMPULSE(3)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -3994,20 +3932,20 @@ static INPUT_PORTS_START( bonuspkr )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Deal / Draw")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)") PORT_CODE(KEYCODE_Q)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Off (Payout)") PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_IMPULSE(3) PORT_NAME("Out (Manual Collect)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_NAME("Off (Payout)")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -4056,9 +3994,9 @@ INPUT_PORTS_END
static INPUT_PORTS_START( super21p )
// Multiplexed - 4x5bits
PORT_START("IN0-0")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET ) PORT_NAME("Bet")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_BET )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_NAME("Meters")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP ) PORT_NAME("Double Up")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_DEAL ) PORT_NAME("Hit")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_POKER_CANCEL ) PORT_NAME("Not Use")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -4066,11 +4004,11 @@ static INPUT_PORTS_START( super21p )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN0-1")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_NAME("Not Use") PORT_CODE(KEYCODE_L)
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Key Pay") PORT_CODE(KEYCODE_W)
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take Score")
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_NAME("Not Use") PORT_CODE(KEYCODE_L)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) PORT_NAME("Key Pay")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_GAMBLE_TAKE ) PORT_NAME("Take Score")
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_HIGH ) PORT_NAME("Big")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_GAMBLE_LOW ) PORT_NAME("Small")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
diff --git a/src/mame/layout/mdndclab.lay b/src/mame/layout/mdndclab.lay
index fe8c95d9883..1f3b68a26e0 100644
--- a/src/mame/layout/mdndclab.lay
+++ b/src/mame/layout/mdndclab.lay
@@ -29,11 +29,11 @@ license:CC0
return nil
end
last_state = true
- local h = target:height()
- local w = target:width()
- local x0, x1, y0, y1 = target:view_bounds()
- local vw = (x1 - x0)
- local vh = (y1 - y0)
+ local h = target.height
+ local w = target.width
+ local vb = target.current_view.bounds
+ local vw = (vb.x1 - vb.x0)
+ local vh = (vb.y1 - vb.y0)
if machine:options().entries.keepaspect:value() then
if (vh / h) < (vw / w) then
local oh = h
@@ -46,8 +46,8 @@ license:CC0
end
end
- x = ((x / w) * vw) + x0
- y = ((y / h) * vh) + y0
+ x = ((x / w) * vw) + vb.x0
+ y = ((y / h) * vh) + vb.y0
return x, y
end
diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp
index 176472b28ef..5027455dfb6 100644
--- a/src/osd/windows/window.cpp
+++ b/src/osd/windows/window.cpp
@@ -1236,8 +1236,8 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
auto const ticks = std::chrono::steady_clock::now();
window->machine().ui_input().push_mouse_down_event(window->m_target, GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
- // check for a double-click
- if (ticks - window->m_lastclicktime < std::chrono::milliseconds(GetDoubleClickTime()) &&
+ // check for a double-click - avoid overflow by adding times rather than subtracting
+ if (ticks < (window->m_lastclicktime + std::chrono::milliseconds(GetDoubleClickTime())) &&
GET_X_LPARAM(lparam) >= window->m_lastclickx - 4 && GET_X_LPARAM(lparam) <= window->m_lastclickx + 4 &&
GET_Y_LPARAM(lparam) >= window->m_lastclicky - 4 && GET_Y_LPARAM(lparam) <= window->m_lastclicky + 4)
{