diff options
68 files changed, 1312 insertions, 871 deletions
diff --git a/docs/source/techspecs/luaengine.rst b/docs/source/techspecs/luaengine.rst index 68790f108ae..d133ce1f51a 100644 --- a/docs/source/techspecs/luaengine.rst +++ b/docs/source/techspecs/luaengine.rst @@ -117,10 +117,10 @@ screens: :: - [MAME]> for tag, screen in pairs(manager:machine().screens) do print(tag) end + [MAME]> for tag, screen in pairs(manager.machine.screens) do print(tag) end :screen -``manager:machine()`` is the root object of your currently running machine: we +``manager.machine`` is the root object of your currently running machine: we will be using this often. ``screens`` is a table with all available screens; most machines only have one main screen. In our case, the main and only screen is tagged as ``:screen``, and we can further inspect it: @@ -128,7 +128,7 @@ is tagged as ``:screen``, and we can further inspect it: :: [MAME]> -- keep a reference to the main screen in a variable - [MAME]> s = manager:machine().screens[":screen"] + [MAME]> s = manager.machine.screens[":screen"] [MAME]> print(s.width .. "x" .. s.height) 320x224 @@ -160,7 +160,7 @@ Similarly to screens, you can inspect all the devices attached to a machine: :: - [MAME]> for tag, device in pairs(manager:machine().devices) do print(tag) end + [MAME]> for tag, device in pairs(manager.machine.devices) do print(tag) end :audiocpu :maincpu :saveram @@ -172,7 +172,7 @@ On some of them, you can also inspect and manipulate memory and state: :: - [MAME]> cpu = manager:machine().devices[":maincpu"] + [MAME]> cpu = manager.machine.devices[":maincpu"] [MAME]> -- enumerate, read and write state registers [MAME]> for k, v in pairs(cpu.state) do print(k) end D5 diff --git a/docs/source/techspecs/luareference.rst b/docs/source/techspecs/luareference.rst index a1042f38db1..deb3d65663d 100644 --- a/docs/source/techspecs/luareference.rst +++ b/docs/source/techspecs/luareference.rst @@ -58,6 +58,512 @@ c:index_of(v) value. +.. _luareference-core: + +Core classes +------------ + +Many of MAME’s core classes used to implement an emulation session are available +to Lua scripts. + +.. _luareference-core-mameman: + +MAME machine manager +~~~~~~~~~~~~~~~~~~~~ + +Wraps MAME’s ``mame_machine_manager`` class, which holds the running machine, UI +manager, and other global components. + +Instantiation +^^^^^^^^^^^^^ + +manager + The MAME machine manager is available as a global variable in the Lua + environment. + +Properties +^^^^^^^^^^ + +manager.machine (read-only) + The :ref:`running machine <luareference-core-machine>` for the current + emulation session. +manager.ui (read-only) + The :ref:`UI manager <luareference-core-uiman>` for the current session. +manager.options (read-only) + The :ref:`emulation options <luareference-core-emuopts>` for the current + session. +manager.plugins[] (read-only) + Gets information about the :ref:`Lua plugins <luareference-core-plugin>` + that are present, indexed by name. The index get, ``at`` and ``index_of`` + methods have O(n) complexity. + +.. _luareference-core-machine: + +Running machine +~~~~~~~~~~~~~~~ + +Wraps MAME’s ``running_machine`` class, which represents an emulation session. +It provides access to the other core objects that implement an emulation session +as well as the emulated device tree. + +Instantiation +^^^^^^^^^^^^^ + +manager:machine() + Gets the running machine instance for the current emulation session. + +Methods +^^^^^^^ + +machine:exit() + Schedules an exit from the current emulation session. This will either + return to the system selection menu or exit the application, depending on + how it was started. This method returns immediately, before the scheduled + exit takes place. +machine:hard_reset() + Schedules a hard reset. This is implemented by tearing down the emulation + session and starting another emulation session for the same system. This + method returns immediately, before the scheduled reset takes place. +machine:soft_reset() + Schedules a soft reset. This is implemented by calling the reset method of + the root device, which is propagated down the device tree. This method + returns immediately, before the scheduled reset takes place. +machine:save(filename) + Schedules saving machine state to the specified file. If the file name is a + relative path, it is considered to be relative to the first configured save + state directory. This method returns immediately, before the machine state + is saved. If this method is called when a save or load operation is already + pending, the previously pending operation will be cancelled. +machine:load(filename) + Schedules loading machine state from the specified file. If the file name + is a relative path, the configured save state directories will be searched. + This method returns immediately, before the machine state is saved. If this + method is called when a save or load operation is already pending, the + previously pending operation will be cancelled. +machine:popmessage([msg]) + Displays a pop-up message to the user. If the message is not provided, the + currently displayed pop-up message (if any) will be hidden. +machine:logerror(msg) + Writes the message to the machine error log. This may be displayed in a + debugger window, written to a file, or written to the standard error output. + +Properties +^^^^^^^^^^ + +machine.system (read-only) + The :ref:`driver metadata <luareference-core-driver>` for the current + system. +machine.parameters (read-only) + The :ref:`parameters manager <luareference-core-paramman>` for the current + emulation session. +machine.video (read-only) + The :ref:`video manager <luareference-core-videoman>` for the current + emulation session. +machine.sound (read-only) + The :ref:`sound manager <luareference-core-soundman>` for the current + emulation session. +machine.output (read-only) + The :ref:`output manager <luareference-core-outputman>` for the current + emulation session. +machine.memory (read-only) + The :ref:`emulated memory manager <luareference-mem-manager>` for the + current emulation session. +machine.ioport (read-only) + The :ref:`I/O port manager <luareference-input-ioportman>` for the current + emulation session. +machine.input (read-only) + The :ref:`input manager <luareference-input-inputman>` for the current + emulation session. +machine.uiinput (read-only) + The :ref:`UI input manager <luareference-input-uiinput>` for the current + emulation session. +machine.render (read-only) + The :ref:`render manager <luareference-render-manager>` for the current + emulation session. +machine.debugger (read-only) + The :ref:`debugger manager <luareference-debug-manager>` for the current + emulation session, or ``nil`` if the debugger is not enabled. +machine.options (read-only) + The user-specified :ref:`options <luareference-core-emuopts>` for the + current emulation session. +machine.samplerate (read-only) + The output audio sample rate in Hertz. +machine.paused (read-only) + A Boolean indicating whether emulation is not currently running, usually + because the session has been paused or the emulated system has not completed + starting. +machine.exit_pending (read-only) + A Boolean indicating whether the emulation session is scheduled to exit. +machine.hard_reset_pending (read-only) + A Boolean indicating whether a hard reset of the emulated system is pending. +machine.devices (read-only) + A :ref:`device enumerator <luareference-dev-enum>` that yields all + :ref:`devices <luareference-dev-device>` in the emulated system. +machine.screens (read-only) + A :ref:`device enumerator <luareference-dev-enum>` that yields all + :ref:`screen devices <luareference-dev-screen>` in the emulated system. +machine.cassettes (read-only) + A :ref:`device enumerator <luareference-dev-enum>` that yields all + :ref:`cassette image devices <luareference-dev-cass>` in the emulated + system. +machine.images (read-only) + A :ref:`device enumerator <luareference-dev-enum>` that yields all + :ref:`media image devices <luareference-dev-diimage>` in the emulated system. +machine.slots (read-only) + A :ref:`device enumerator <luareference-dev-enum>` that yields all + :ref:`slot devices <luareference-dev-dislot>` in the emulated system. + +.. _luareference-core-videoman: + +Video manager +~~~~~~~~~~~~~ + +Wraps MAME’s ``video_manager`` class, which is responsible for coordinating +emulated video drawing, speed throttling, and reading host inputs. + +Instantiation +^^^^^^^^^^^^^ + +manager:machine().video + Gets the video manager for the current emulation session. + +Methods +^^^^^^^ + +video:frame_update() + Updates emulated screens, reads host inputs, and updates video output. +video:snapshot() + Saves snapshot files according to the current configuration. If MAME is + configured to take native emulated screen snapshots, one snapshot will be + saved for each emulated screen that is visible in a host window/screen with + the current view configuration. If MAME is not configured to use take + native emulated screen snapshots or if the system has no emulated screens, a + single snapshot will be saved using the currently selected snapshot view. +video:begin_recording([filename], [format]) + Stops any video recordings currently in progress and starts recording either + the visible emulated screens or the current snapshot view, depending on + whether MAME is configured to take native emulated screen snapshots. + + If the file name is not supplied, the configured snapshot file name is used. + If the file name is a relative path, it is interpreted relative to the first + configured snapshot directory. If the format is supplied, it must be + ``"avi"`` or ``"mng"``. If the format is not supplied, it defaults to AVI. +video:end_recording() + Stops any video recordings that are in progress. +video:snapshot_size() + Returns the width and height in pixels of snapshots created with the current + snapshot target configuration and emulated screen state. This may be + configured explicitly by the user, or calculated based on the selected + snapshot view and the resolution of any visible emulated screens. +video:snapshot_pixels() + Returns the pixels of a snapshot created using the current snapshot target + configuration as 32-bit integers packed into a binary string in host Endian + order. Pixels are organised in row-major order, from left to right then top + to bottom. Pixel values are colours in RGB format packed into 32-bit + integers. + +Properties +^^^^^^^^^^ + +video.speed_factor (read-only) + Configured emulation speed adjustment in per mille (i.e. the ratio to normal + speed multiplied by 1,000). +video.throttled (read/write) + A Boolean indicating whether MAME should wait before video updates to avoid + running faster than the target speed. +video.throttle_rate (read/write) + The target emulation speed as a ratio of full speed adjusted by the speed + factor (i.e. 1 is normal speed adjusted by the speed factor, larger numbers + are faster, and smaller numbers are slower). +video.frameskip (read/write) + The number of emulated video frames to skip drawing out of every twelve, or + -1 to automatically adjust the number of frames to skip to maintain the + target emulation speed. +video.speed_percent (read-only) + The current emulated speed as a percentage of the full speed adjusted by the + speed factor. +video.effective_frameskip (read-only) + The number of emulated frames that are skipped out of every twelve. +video.skip_this_frame (read-only) + A Boolean indicating whether the video manager will skip drawing emulated + screens for the current frame. +video.snap_native (read-only) + A Boolean indicating whether the video manager will take native emulated + screen snapshots. In addition to the relevant configuration setting, the + emulated system must have at least one emulated screen. +video.is_recording (read-only) + A Boolean indicating whether any video recordings are currently in progress. +video.snapshot_target (read-only) + The :ref:`render target <luareference-render-target>` used to produce + snapshots and video recordings. + +.. _luareference-core-soundman: + +Sound manager +~~~~~~~~~~~~~ + +Wraps MAME’s ``sound_manager`` class, which manages the emulated sound stream +graph and coordinates sound output. + +Instantiation +^^^^^^^^^^^^^ + +manager:machine().sound + Gets the sound manager for the current emulation session. + +Methods +^^^^^^^ + +sound:start_recording([filename]) + Starts recording to a WAV file. Has no effect if currently recording. If + the file name is not supplied, uses the configured WAV file name (from + command line or INI file), or has no effect if no WAV file name is + configured. Returns ``true`` if recording started, or ``false`` if + recording is already in progress, opening the output file failed, or no file + name was supplied or configured. +sound:stop_recording() + Stops recording and closes the file if currently recording to a WAV file. +sound:get_samples() + Returns the current contents of the output sample buffer as a binary string. + Samples are 16-bit integers in host byte order. Samples for left and right + stereo channels are interleaved. + +Properties +^^^^^^^^^^ + +sound.muted (read-only) + A Boolean indicating whether sound output is muted for any reason. +sound.ui_mute (read/write) + A Boolean indicating whether sound output is muted at the request of the + user. +sound.debugger_mute (read/write) + A Boolean indicating whether sound output is muted at the request of the + debugger. +sound.system_mute (read/write) + A Boolean indicating whether sound output is muted at the request of the + emulated system. +sound.attenuation (read/write) + The output volume attenuation in decibels. Should generally be a negative + integer or zero. +sound.recording (read-only) + A Boolean indicating whether sound output is currently being recorded to a + WAV file. + +.. _luareference-core-outputman: + +Output manager +~~~~~~~~~~~~~~ + +Wraps MAME’s ``output_manager`` class, providing access to system outputs that +can be used for interactive artwork or consumed by external programs. + +Instantiation +^^^^^^^^^^^^^ + +manager:machine().output + Gets the output manager for the current emulation session. + +Methods +^^^^^^^ + +output:set_value(name, val) + Sets the specified output value. The value must be an integer. The output + will be created if it does not already exist. +output:set_indexed_value(prefix, index, val) + Appends the index (formatted as a decimal integer) to the prefix and sets + the value of the corresponding output. The value must be an integer. The + output will be created if it does not already exist. +output:get_value(name) + Returns the value of the specified output, or zero if it doesn’t exist. +output:get_indexed_value(prefix, index) + Appends the index (formatted as a decimal integer) to the prefix and returns + the value of the corresponding output, or zero if it doesn’t exist. +output:name_to_id(name) + Gets the per-session unique integer ID for the specified output, or zero if + it doesn’t exist. +output:id_to_name(id) + Gets the name for the output with the specified per-session unique ID, or + ``nil`` if it doesn’t exist. This method has O(n) complexity, so avoid + calling it when performance is important. + +.. _luareference-core-paramman: + +Parameters manager +~~~~~~~~~~~~~~~~~~ + +Wraps MAME’s ``parameters_manager`` class, which provides a simple key-value +store for metadata from system ROM definitions. + +Instantiation +^^^^^^^^^^^^^ + +manager:machine().parameters + Gets the parameters manager for the current emulation session. + +Methods +^^^^^^^ + +parameters:lookup(tag) + Gets the value for the specified parameter if it is set, or an empty string + if it is not set. +parameters:add(tag, value) + Sets the specified parameter if it is not set. Has no effect if the + specified parameter is already set. + +.. _luareference-core-uiman: + +UI manager +~~~~~~~~~~ + +Wraps MAME’s ``mame_ui_manager`` class, which handles menus and other user +interface functionality. + +Instantiation +^^^^^^^^^^^^^ + +manager.ui + Gets the UI manager for the current session. + +Methods +^^^^^^^ + +ui:get_char_width(ch) + Gets the width of a Unicode character as a proportion of the width of the UI + container in the current font at the configured UI line height. +ui:get_string_width(str) + Gets the width of a string as a proportion of the width of the UI container + in the current font at the configured UI line height. +ui:set_aggressive_input_focus(enable) + On some platforms, this controls whether MAME should accept input focus in + more situations than when its windows have UI focus. + +Properties +^^^^^^^^^^ + +ui.options (read-only) + The UI :ref:`options <luareference-core-coreopts>` for the current session. +ui.line_height (read-only) + The configured UI text line height as a proportion of the height of the UI + container. +ui.menu_active (read-only) + A Boolean indicating whether an interactive UI element is currently active. + Examples include menus and slider controls. +ui.single_step (read/write) + A Boolean controlling whether the emulated system should be automatically + paused when the next frame is drawn. This property is automatically reset + when the automatic pause happens. +ui.show_fps (read/write) + A Boolean controlling whether the current emulation speed and frame skipping + settings should be displayed. +ui.show_profiler (read/write) + A Boolean controlling whether profiling statistics should be displayed. + +.. _luareference-core-driver: + +System driver metadata +~~~~~~~~~~~~~~~~~~~~~~ + +Provides some metadata for an emulated system. + +Instantiation +^^^^^^^^^^^^^ + +emu.driver_find(name) + Gets the driver metadata for the system with the specified short name, or + ``nil`` if no such system exists. +manager.machine.system + Gets the driver metadata for the current system. + +Properties +^^^^^^^^^^ + +driver.name (read-only) + The short name of the system, as used on the command line, in configuration + files, and when searching for resources. +driver.description (read-only) + The full display name for the system. +driver.year (read-only) + The release year for the system. May contain question marks if not known + definitively. +driver.manufacturer (read-only) + The manufacturer, developer or distributor of the system. +driver.parent (read-only) + The short name of parent system for organisation purposes, or ``"0"`` if the + system has no parent. +driver.compatible_with (read-only) + The short name of a system that this system is compatible with software for, + or ``nil`` if the system is not listed as compatible with another system. +driver.source_file (read-only) + The source file where this system driver is defined. The path format + depends on the toolchain the emulator was built with. +driver.rotation (read-only) + A string indicating the rotation applied to all screens in the system after + the screen orientation specified in the machine configuration is applied. + Will be one of ``"rot0"``, ``"rot90"``, ``"rot180"`` or ``"rot270"``. +driver.type (read-only) + A string providing a system type. Will be one of ``"arcade"``, + ``"console"``, ``"computer"`` or ``"other"``. This is for informational + purposes only, and may not be supported in the future. +driver.not_working (read-only) + A Boolean indicating whether the system is marked as not working. +driver.supports_save (read-only) + A Boolean indicating whether the system supports save states. +driver.no_cocktail (read-only) + A Boolean indicating whether screen flipping in cocktail mode is + unsupported. +driver.is_bios_root (read-only) + A Boolean indicating whether this system represents a system that runs + software from removable media without media present. +driver.requires_artwork (read-only) + A Boolean indicating whether the system requires external artwork to be + usable. +driver.clickable_artwork (read-only) + A Boolean indicating whether the system requires clickable artwork features + to be usable. +driver.unofficial (read-only) + A Boolean indicating whether this is an unofficial but common user + modification to a system. +driver.no_sound_hw (read-only) + A Boolean indicating whether the system has no sound output hardware. +driver.mechanical (read-only) + A Boolean indicating whether the system depends on mechanical features that + cannot be properly simulated. +driver.is_incomplete (read-only) + A Boolean indicating whether the system is a prototype with incomplete + functionality. + +.. _luareference-core-plugin: + +Lua plugin +~~~~~~~~~~ + +Provides a description of an available Lua plugin. + +Instantiation +^^^^^^^^^^^^^ + +manager.plugins[name] + Gets the description of the Lua plugin with the specified name, or ``nil`` + if no such plugin is available + +Properties +^^^^^^^^^^ + +plugin.name (read-only) + The short name of the plugin, used in configuration and when accessing the + plugin programmatically. +plugin.description (read-only) + The display name for the plugin. +plugin.type (read-only) + The plugin type. May be ``"plugin"`` for user-loadable plugins, or + ``"library"`` for libraries providing common functionality to multiple + plugins. +plugin.directory (read-only) + The path to the directory containing the plugin’s files. +plugin.start (read-only) + A Boolean indicating whether the plugin enabled. + + .. _luareference-dev: Devices @@ -112,7 +618,7 @@ manager:machine().screens :ref:`screen devices <luareference-dev-screen>` in the system. manager:machine().cassettes Returns a device enumerator that will iterate over - :ref:`cassette devices <luareference-dev-cass>` in the system. + :ref:`cassette image devices <luareference-dev-cass>` in the system. manager:machine().images Returns a device enumerator that will iterate over :ref:`media image devices <luareference-dev-diimage>` in the system. @@ -135,11 +641,12 @@ emu.screen_enumerator(device, [depth]) will limit iteration to the device and its immediate children). emu.cassette_enumerator(device, [depth]) Returns a device enumerator that will iterate over - :ref:`cassette devices <luareference-dev-cass>` in the sub-tree starting at - the specified device. The specified device will be included if it is a - cassette device. If the depth is provided, it must be an integer specifying - the maximum number of levels to iterate below the specified device (i.e. 1 - will limit iteration to the device and its immediate children). + :ref:`cassette image devices <luareference-dev-cass>` in the sub-tree + starting at the specified device. The specified device will be included if + it is a cassette image device. If the depth is provided, it must be an + integer specifying the maximum number of levels to iterate below the + specified device (i.e. 1 will limit iteration to the device and its + immediate children). emu.image_enumerator(device, [depth]) Returns a device enumerator that will iterate over :ref:`media image devices <luareference-dev-diimage>` in the sub-tree @@ -196,6 +703,9 @@ device:subdevice(tag) Gets a device by tag relative to the device. device:siblingdevice(tag) Gets a device by tag relative to the device’s parent. +device:parameter(tag) + Gets a parameter value by tag relative to the device, or an empty string if + the parameter is not set. Properties ^^^^^^^^^^ @@ -252,7 +762,9 @@ Methods screen:orientation() Returns the rotation angle in degrees (will be one of 0, 90, 180 or 270), whether the screen is flipped left-to-right, and whether the screen is - flipped top-to-bottom. + flipped top-to-bottom. This is the final screen orientation after the + screen orientation specified in the machine configuration and the rotation + for the system driver are applied. screen:time_until_pos(v, [h]) Gets the time remaining until the raster reaches the specified position. If the horizontal component of the position is not specified, it defaults to @@ -675,7 +1187,7 @@ regions in a system to be enumerated. Instantiation ^^^^^^^^^^^^^ -manager:machine():memory() +manager:machine().memory Gets the global memory manager instance for the emulated system. Properties @@ -902,7 +1414,7 @@ Wraps MAME’s ``memory_share`` class, representing a named allocated memory zon Instantiation ^^^^^^^^^^^^^ -manager:machine():memory().shares[tag] +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) @@ -952,7 +1464,7 @@ indirection. Instantiation ^^^^^^^^^^^^^ -manager:machine():memory().banks[tag] +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) @@ -978,7 +1490,7 @@ read-only data like ROMs or the result of fixed decryptions. Instantiation ^^^^^^^^^^^^^ -manager:machine():memory().regions[tag] +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) @@ -1037,7 +1549,7 @@ ports and handles input configuration. Instantiation ^^^^^^^^^^^^^ -manager:machine():ioport() +manager:machine().ioport Gets the global I/O port manager instance for the emulated machine. Methods @@ -1079,7 +1591,7 @@ keypad inputs. Instantiation ^^^^^^^^^^^^^ -manager:machine():ioport().natkeyboard +manager:machine().ioport.natkeyboard Gets the global natural keyboard manager instance for the emulated machine. Methods @@ -1143,7 +1655,7 @@ Represents a keyboard or keypad input device managed by the Instantiation ^^^^^^^^^^^^^ -manager:machine():ioport().natkeyboard.keyboards[tag] +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. @@ -1179,7 +1691,7 @@ Wraps MAME’s ``ioport_port`` class, representing an emulated I/O port. Instantiation ^^^^^^^^^^^^^ -manager:machine():ioport().ports[tag] +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) @@ -1225,9 +1737,9 @@ Wraps MAME’s ``ioport_field`` class, representing a field within an I/O port. Instantiation ^^^^^^^^^^^^^ -manager:machine():ioport().ports[tag]:field[mask] +manager:machine().ioport.ports[tag]:field[mask] Gets a field for the given port by bit mask. -manager:machine():ioport().ports[tag].fields[name] +manager:machine().ioport.ports[tag].fields[name] Gets a field for the given port by display name. Methods @@ -1348,7 +1860,7 @@ port field. Instantiation ^^^^^^^^^^^^^ -manager:machine():ioport().ports[tag]:field(mask).live +manager:machine().ioport.ports[tag]:field(mask).live Gets the live state for an I/O port field. Properties @@ -1368,7 +1880,7 @@ whether configured inputs are active. Instantiation ^^^^^^^^^^^^^ -manager:machine():input() +manager:machine().input Gets the global input manager instance for the emulated system. Methods @@ -1443,12 +1955,12 @@ activated. Instantiation ^^^^^^^^^^^^^ -manager:machine():input():axis_code_poller() +manager:machine().input:axis_code_poller() Returns an input code poller that polls for analog inputs being activated. -manager:machine():input():switch_code_poller() +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() +manager:machine().input:keyboard_code_poller() Returns an input code poller that polls for host switch inputs being activated, only considering keyboard input devices. @@ -1474,10 +1986,10 @@ assign host input combinations to emulated inputs and other actions. Instantiation ^^^^^^^^^^^^^ -manager:machine():input():axis_sequence_poller() +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() +manager:machine().input:switch_sequence_poller() Returns an input sequence poller for assigning host inputs to a switch input. @@ -1517,7 +2029,7 @@ devices (e.g. keyboards or joysticks). Instantiation ^^^^^^^^^^^^^ -manager:machine():input().device_classes[name] +manager:machine().input.device_classes[name] Gets an input device class by name. Properties @@ -1545,7 +2057,7 @@ Wraps MAME’s ``input_device`` class, representing a host input device. Instantiation ^^^^^^^^^^^^^ -manager:machine():input().device_classes[name].devices[index] +manager:machine().input.device_classes[name].devices[index] Gets a specific host input device. Properties @@ -1574,7 +2086,7 @@ a key, button, or axis). Instantiation ^^^^^^^^^^^^^ -manager:machine():input().device_classes[name].devices[index].items[id] +manager:machine().input.device_classes[name].devices[index].items[id] Gets an individual host input item. The item ID is an enumerated value. Properties @@ -1607,7 +2119,7 @@ Wraps MAME’s ``ui_input_manager`` class, which is used for high-level input. Instantiation ^^^^^^^^^^^^^ -manager:machine():uiinput() +manager:machine().uiinput Gets the global UI input manager instance for the machine. Methods @@ -1775,7 +2287,7 @@ and textures. Instantiation ^^^^^^^^^^^^^ -manager:machine():render() +manager:machine().render Gets the global render manager instance for the emulation session. Properties @@ -1808,12 +2320,14 @@ screenshots. Instantiation ^^^^^^^^^^^^^ -manager:machine():render().targets[index] - Get a render target by index. -manager:machine():render():ui_target() - Get the render target used to display the user interface (including menus, +manager:machine().render.targets[index] + Gets a render target by index. +manager:machine().render.ui_target + Gets the render target used to display the user interface (including menus, sliders and pop-up messages). This is usually the first host window or screen. +manager:machine().video.snapshot_target + Gets the render target used to produce snapshots and video recordings. Properties ^^^^^^^^^^ @@ -1870,7 +2384,7 @@ Wraps MAME’s ``render_container`` class. Instantiation ^^^^^^^^^^^^^ -manager:machine():render().ui_container +manager:machine().render.ui_container Gets the render container used to draw the user interface, including menus, sliders and pop-up messages. manager:machine().screens[tag].container @@ -2000,7 +2514,7 @@ Instantiation Layout scripts generally -manager:machine():render().targets[index].current_view +manager:machine().render.targets[index].current_view Gets the currently selected view for a given render target. Methods @@ -2183,7 +2697,7 @@ the debugger. Instantiation ^^^^^^^^^^^^^ -manager:machine():debugger() +manager:machine().debugger Returns the global debugger manager instance, or ``nil`` if the debugger is not enabled. diff --git a/plugins/autofire/autofire_menu.lua b/plugins/autofire/autofire_menu.lua index b9fb89d5042..14ad0ea0634 100644 --- a/plugins/autofire/autofire_menu.lua +++ b/plugins/autofire/autofire_menu.lua @@ -63,7 +63,7 @@ local function populate_main_menu(buttons) -- Round to two decimal places rate = math.floor(rate * 100) / 100 local text = button.button.name .. ' [' .. rate .. ' Hz]' - local subtext = manager:machine():input():seq_name(button.key) + local subtext = manager.machine.input:seq_name(button.key) menu[#menu + 1] = {text, subtext, ''} end content_height = #menu @@ -76,7 +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')) + manager.machine:popmessage(_('Press UI Clear to delete')) if event == 'select' then current_button = buttons[adjusted_index] table.insert(menu_stack, MENU_TYPES.EDIT) @@ -99,7 +99,7 @@ end local function populate_configure_menu(menu) local button_name = current_button.button and current_button.button.name or _('NOT SET') - local key_name = current_button.key and manager:machine():input():seq_name(current_button.key) or _('NOT SET') + local key_name = current_button.key and manager.machine.input:seq_name(current_button.key) or _('NOT SET') menu[#menu + 1] = {_('Input'), button_name, ''} menu[#menu + 1] = {_('Hotkey'), key_name, ''} menu[#menu + 1] = {_('On frames'), current_button.on_frames, current_button.on_frames > 1 and 'lr' or 'r'} @@ -108,26 +108,26 @@ end -- Borrowed from the cheat plugin local function poll_for_hotkey() - local input = manager:machine():input() + local input = manager.machine.input local poller = input:switch_sequence_poller() - manager:machine():popmessage(_('Press button for hotkey or wait to leave unchanged')) - manager:machine():video():frame_update(true) + manager.machine:popmessage(_('Press button for hotkey or wait to leave unchanged')) + manager.machine.video:frame_update() poller:start() local time = os.clock() local clearmsg = true while (not poller:poll()) and (poller.modified or (os.clock() < time + 1)) do if poller.modified then if not poller.valid then - manager:machine():popmessage(_("Invalid sequence entered")) + manager.machine:popmessage(_("Invalid sequence entered")) clearmsg = false break end - manager:machine():popmessage(input:seq_name(poller.sequence)) - manager:machine():video():frame_update(true) + manager.machine:popmessage(input:seq_name(poller.sequence)) + manager.machine.video:frame_update() end end if clearmsg then - manager:machine():popmessage() + manager.machine:popmessage() end return poller.valid and poller.sequence or nil end @@ -156,7 +156,7 @@ local function handle_configure_menu(index, event) end elseif index == 3 then -- On frames - manager:machine():popmessage(_('Number of frames button will be pressed')) + 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 @@ -164,7 +164,7 @@ local function handle_configure_menu(index, event) end elseif index == 4 then -- Off frames - manager:machine():popmessage(_('Number of frames button will be released')) + manager.machine:popmessage(_('Number of frames button will be released')) if event == 'left' then current_button.off_frames = current_button.off_frames - 1 elseif event == 'right' then @@ -244,7 +244,7 @@ local function populate_button_menu() menu[#menu + 1] = {'---', '', ''} header_height = #menu - for port_key, port in pairs(manager:machine():ioport().ports) do + for port_key, port in pairs(manager.machine.ioport.ports) do for field_key, field in pairs(port.fields) do if is_supported_input(field) then menu[#menu + 1] = {field.name, '', ''} @@ -295,7 +295,7 @@ function lib:populate_menu(buttons) end function lib:handle_menu_event(index, event, buttons) - manager:machine():popmessage() + manager.machine:popmessage() local current_menu = menu_stack[#menu_stack] if current_menu == MENU_TYPES.MAIN then return handle_main_menu(index, event, buttons) diff --git a/plugins/autofire/autofire_save.lua b/plugins/autofire/autofire_save.lua index 07c4032b434..0576a95582d 100644 --- a/plugins/autofire/autofire_save.lua +++ b/plugins/autofire/autofire_save.lua @@ -1,7 +1,7 @@ local lib = {} local function get_settings_path() - return emu.subst_env(manager:machine():options().entries.homepath:value():match('([^;]+)')) .. '/autofire/' + return emu.subst_env(manager.machine.options.entries.homepath:value():match('([^;]+)')) .. '/autofire/' end local function get_settings_filename() @@ -13,12 +13,12 @@ local function initialize_button(settings) local new_button = { port = settings.port, field = settings.field, - key = manager:machine():input():seq_from_tokens(settings.key), + key = manager.machine.input:seq_from_tokens(settings.key), on_frames = settings.on_frames, off_frames = settings.off_frames, counter = 0 } - local port = manager:machine():ioport().ports[settings.port] + local port = manager.machine.ioport.ports[settings.port] if port then local field = port.fields[settings.field] if field then @@ -36,7 +36,7 @@ local function serialize_settings(button_list) setting = { port = button.port, field = button.field, - key = manager:machine():input():seq_to_tokens(button.key), + key = manager.machine.input:seq_to_tokens(button.key), on_frames = button.on_frames, off_frames = button.off_frames } diff --git a/plugins/autofire/init.lua b/plugins/autofire/init.lua index da9a223faa4..72ee65672d4 100644 --- a/plugins/autofire/init.lua +++ b/plugins/autofire/init.lua @@ -24,7 +24,7 @@ function autofire.startplugin() local current_rom = nil local function process_button(button) - local pressed = manager:machine():input():seq_pressed(button.key) + local pressed = manager.machine.input:seq_pressed(button.key) if pressed then local state = button.counter < button.on_frames and 1 or 0 button.counter = (button.counter + 1) % (button.on_frames + button.off_frames) @@ -59,7 +59,7 @@ function autofire.startplugin() local function reinit_buttons() for i, button in ipairs(buttons) do button.counter = 0 - button.button = manager:machine():ioport().ports[button.port].fields[button.field] + button.button = manager.machine.ioport.ports[button.port].fields[button.field] end end diff --git a/plugins/boot.lua b/plugins/boot.lua index 3a4de6fcc7c..8ae3e069755 100644 --- a/plugins/boot.lua +++ b/plugins/boot.lua @@ -5,7 +5,7 @@ require('lfs') _G._ = emu.lang_translate _G.emu.plugin = {} -- table to contain plugin interfaces -- substitute environment variables in the plugins path from options -local dirs = emu.subst_env(manager:options().entries.pluginspath:value()) +local dirs = emu.subst_env(manager.options.entries.pluginspath:value()) -- and split the paths apart and make them suitable for package.path package.path = "" @@ -16,7 +16,7 @@ for dir in string.gmatch(dirs, "([^;]+)") do package.path = package.path .. dir .. "/?.lua;" .. dir .. "/?/init.lua" end -for _,entry in pairs(manager:plugins()) do +for _,entry in pairs(manager.plugins) do if (entry.type == "plugin" and entry.start) then emu.print_verbose("Starting plugin " .. entry.name .. "...") plugin = require(entry.name) diff --git a/plugins/cheat/cheat_simple.lua b/plugins/cheat/cheat_simple.lua index 9640cf22bc6..f65cc9e46b7 100644 --- a/plugins/cheat/cheat_simple.lua +++ b/plugins/cheat/cheat_simple.lua @@ -48,7 +48,7 @@ local function prepare_rom_cheat(desc, region, addr, val, size, banksize, comp) end if banksize and comp then - local rom = manager:machine():memory().regions[region] + local rom = manager.machine.memory.regions[region] local bankaddr = addr & (banksize - 1) addr = nil if not rom then @@ -92,7 +92,7 @@ function codefuncs.nes_gg(desc, code) if #code == 6 then addr = ((value >> 4) & 7) | ((value >> 8) & 0x78) | ((value >> 12) & 0x80) | ((value << 8) & 0x700) | ((value << 4) & 0x7800) newval = ((value >> 20) & 7) | (value & 8) | ((value >> 12) & 0x70) | ((value >> 16) & 0x80) - if manager:machine():memory().regions[":nes_slot:cart:prg_rom"].size > 32768 then + if manager.machine.memory.regions[":nes_slot:cart:prg_rom"].size > 32768 then emu.print_verbose("warning: gamegenie 6 char code with banked rom " .. desc) end return prepare_rom_cheat(desc, ":nes_slot:cart:prg_rom", addr, newval, 8) @@ -130,7 +130,7 @@ local function snes_prepare_cheat(desc, addr, val) if ((bank <= 0x3f) and (offset < 0x2000)) or ((bank & 0xfe) == 0x7e) then return prepare_ram_cheat(desc, ":maincpu", addr, val, 8) end - if (manager:machine().devices[":maincpu"].spaces["program"]:read_u8(0xffd5) & 1) == 1 then --hirom + if (manager.machine.devices[":maincpu"].spaces["program"]:read_u8(0xffd5) & 1) == 1 then --hirom if (bank & 0x7f) <= 0x3f and offset >= 0x8000 then -- direct map elseif (bank & 0x7f) >= 0x40 and (bank & 0x7f) <= 0x7d then @@ -309,7 +309,7 @@ function simple.conv_cheat(data) end offset = tonumber(offset, 16) val = tonumber(val, 16) - if manager:machine().devices[cputag] then + if manager.machine.devices[cputag] then cheat = prepare_ram_cheat(desc, cputag, offset, val, size) else cheat = prepare_rom_cheat(desc, cputag, offset, val, size) diff --git a/plugins/cheat/cheat_xml.lua b/plugins/cheat/cheat_xml.lua index d5cee8ac2a2..d9032814f30 100644 --- a/plugins/cheat/cheat_xml.lua +++ b/plugins/cheat/cheat_xml.lua @@ -59,7 +59,7 @@ function xml.conv_cheat(data) data = xml_parse(data) local cpu_spaces = {} - for tag, device in pairs(manager:machine().devices) do + for tag, device in pairs(manager.machine.devices) do local sp for name, space in pairs(device.spaces) do if not sp then diff --git a/plugins/cheat/init.lua b/plugins/cheat/init.lua index 83dbdc7bfb1..46a086f8ac2 100644 --- a/plugins/cheat/init.lua +++ b/plugins/cheat/init.lua @@ -94,12 +94,12 @@ function cheat.startplugin() local function load_cheats() local filename = emu.romname() local newcheats = {} - local file = emu.file(manager:machine():options().entries.cheatpath:value():gsub("([^;]+)", "%1;%1/cheat") , 1) + local file = emu.file(manager.machine.options.entries.cheatpath:value():gsub("([^;]+)", "%1;%1/cheat") , 1) if emu.softname() ~= "" then if emu.softname():find(":") then filename = emu.softname():gsub(":", "/") else - for name, image in pairs(manager:machine().images) do + for name, image in pairs(manager.machine.images) do if image:exists() and image:software_list_name() ~= "" then filename = image:software_list_name() .. "/" .. emu.softname() end @@ -134,7 +134,7 @@ function cheat.startplugin() local function load_hotkeys() local json = require("json") - local file = io.open(emu.subst_env(manager:machine():options().entries.cheatpath:value():match("([^;]+)")) .. "/" .. cheatname .. "_hotkeys.json", "r") + local file = io.open(emu.subst_env(manager.machine.options.entries.cheatpath:value():match("([^;]+)")) .. "/" .. cheatname .. "_hotkeys.json", "r") if not file then return end @@ -142,7 +142,7 @@ function cheat.startplugin() for num, val in ipairs(hotkeys) do for num, cheat in pairs(cheats) do if val.desc == cheat.desc then - cheat.hotkeys = {pressed = false, keys = manager:machine():input():seq_from_tokens(val.keys)} + cheat.hotkeys = {pressed = false, keys = manager.machine.input:seq_from_tokens(val.keys)} end end end @@ -152,7 +152,7 @@ function cheat.startplugin() local hotkeys = {} for num, cheat in ipairs(cheats) do if cheat.hotkeys then - local hotkey = {desc = cheat.desc, keys = manager:machine():input():seq_to_tokens(cheat.hotkeys.keys)} + local hotkey = {desc = cheat.desc, keys = manager.machine.input:seq_to_tokens(cheat.hotkeys.keys)} if hotkey.keys ~= "" then hotkeys[#hotkeys + 1] = hotkey end @@ -160,7 +160,7 @@ function cheat.startplugin() end if #hotkeys > 0 then local json = require("json") - local path = emu.subst_env(manager:machine():options().entries.cheatpath:value():match("([^;]+)")) + local path = emu.subst_env(manager.machine.options.entries.cheatpath:value():match("([^;]+)")) local attr = lfs.attributes(path) if not attr then lfs.mkdir(path) @@ -215,7 +215,7 @@ function cheat.startplugin() return end if type(x) == "string" then - y = y * mame_manager:ui():get_line_height() + y = y * mame_manager.ui.line_height end output[#output + 1] = { type = "text", scr = screen, x = x, y = y, str = str, color = color } end @@ -278,13 +278,13 @@ function cheat.startplugin() run_if(wp.cheat, wp.func) -- go in case a debugger other than "none" is enabled -- don't use an b/wpset action because that will supress the b/wp index - manager:machine():debugger().execution_state = "run" + manager.machine.debugger.execution_state = "run" end else local bp = breaks[point] if bp then run_if(bp.cheat, bp.func) - manager:machine():debugger().execution_state = "run" + manager.machine.debugger.execution_state = "run" end end end @@ -313,7 +313,7 @@ function cheat.startplugin() end local function bwpclr(cheat) - if not manager:machine():debugger() then + if not manager.machine.debugger then return end for num, bp in pairs(breaks) do @@ -340,7 +340,7 @@ function cheat.startplugin() if entry.port:sub(1, 1) ~= ":" then entry.port = ":" .. entry.port end - local port = manager:machine():ioport().ports[entry.port] + local port = manager.machine.ioport.ports[entry.port] if not port then errout(entry.port, entry.field) end @@ -372,7 +372,7 @@ function cheat.startplugin() error("input_run only allowed in one shot cheats") return end - local _, screen = next(manager:machine().screens) + local _, screen = next(manager.machine.screens) list.begin = screen:frame_number() inputs[#inputs + 1] = list end @@ -451,7 +451,7 @@ function cheat.startplugin() frombcd = frombcd, pairs = pairs, ipairs = ipairs, - outputs = manager:machine():outputs(), + outputs = manager.machine.output, time = time, input_trans = input_trans, input_run = function(list) input_run(cheat, list) end, @@ -483,8 +483,8 @@ function cheat.startplugin() if cheat.cpu then cheat.cpudev = {} for name, tag in pairs(cheat.cpu) do - if manager:machine():debugger() then - local dev = manager:machine().devices[tag] + if manager.machine.debugger then + local dev = manager.machine.devices[tag] if not dev or not dev.debug then cheat_error(cheat, "missing or invalid device " .. tag) return @@ -505,7 +505,7 @@ function cheat.startplugin() if cheat.space then for name, space in pairs(cheat.space) do local cpu, mem - cpu = manager:machine().devices[space.tag] + cpu = manager.machine.devices[space.tag] if not cpu then cheat_error(cheat, "missing device " .. space.tag) return @@ -525,17 +525,17 @@ function cheat.startplugin() end if cheat.screen then for name, screen in pairs(cheat.screen) do - local scr = manager:machine().screens[screen] + local scr = manager.machine.screens[screen] if not scr then local tag - tag, scr = next(manager:machine().screens) -- get any screen + tag, scr = next(manager.machine.screens) -- get any screen end cheat.cheat_env[name] = scr end end if cheat.region then for name, region in pairs(cheat.region) do - local mem = manager:machine():memory().regions[region] + local mem = manager.machine.memory.regions[region] if not mem then cheat_error(cheat, "missing region " .. region) return @@ -545,7 +545,7 @@ function cheat.startplugin() end if cheat.ram then for name, tag in pairs(cheat.ram) do - local ram = manager:machine().devices[tag] + local ram = manager.machine.devices[tag] if not ram then cheat_error(cheat, "missing ram device " .. tag) return @@ -555,7 +555,7 @@ function cheat.startplugin() end if cheat.share then for name, tag in pairs(cheat.share) do - local share = manager:machine():memory().shares[tag] + local share = manager.machine.memory.shares[tag] if not share then cheat_error(cheat, "missing share " .. share) return @@ -615,36 +615,36 @@ function cheat.startplugin() return end - local input = manager:machine():input() + local input = manager.machine.input local poller = input:switch_sequence_poller() - manager:machine():popmessage(_("Press button for hotkey or wait to leave unchanged")) - manager:machine():video():frame_update(true) + manager.machine:popmessage(_("Press button for hotkey or wait to leave unchanged")) + manager.machine.video:frame_update() poller:start() local time = os.clock() local clearmsg = true while (not poller:poll()) and (poller.modified or (os.clock() < time + 1)) do if poller.modified then if not poller.valid then - manager:machine():popmessage(_("Invalid sequence entered")) + manager.machine:popmessage(_("Invalid sequence entered")) clearmsg = false break end - manager:machine():popmessage(input:seq_name(poller.sequence)) - manager:machine():video():frame_update(true) + manager.machine:popmessage(input:seq_name(poller.sequence)) + manager.machine.video:frame_update() end end if poller.modified and poller.valid then cheat.hotkeys = { pressed = false, keys = poller.sequence } end if clearmsg then - manager:machine():popmessage() + manager.machine:popmessage() end - manager:machine():video():frame_update(true) + manager.machine.video:frame_update() end for num, cheat in ipairs(cheats) do if cheat.script then - menu[#menu + 1] = {cheat.desc, cheat.hotkeys and manager:machine():input():seq_name(cheat.hotkeys.keys) or _("None"), ""} + menu[#menu + 1] = {cheat.desc, cheat.hotkeys and manager.machine.input:seq_name(cheat.hotkeys.keys) or _("None"), ""} hotkeylist[#hotkeylist + 1] = function(event) return hkcbfunc(cheat, event) end end end @@ -703,7 +703,7 @@ function cheat.startplugin() end local function menu_callback(index, event) - manager:machine():popmessage() + manager.machine:popmessage() if hotkeymenu then if event == "select" or event == "clear" then index = index - 3 @@ -745,7 +745,7 @@ function cheat.startplugin() end if event == "up" or event == "down" or event == "comment" then if cheat.comment then - manager:machine():popmessage(string.format(_("Cheat Comment:\n%s"), cheat.comment)) + manager.machine:popmessage(string.format(_("Cheat Comment:\n%s"), cheat.comment)) end elseif event == "left" then if cheat.parameter then @@ -779,9 +779,9 @@ function cheat.startplugin() else itemtext = cheat.parameter.value end - manager:machine():popmessage(string.format(_("Activated: %s = %s"), cheat.desc, itemtext)) + manager.machine:popmessage(string.format(_("Activated: %s = %s"), cheat.desc, itemtext)) elseif not cheat.parameter and cheat.script.on then - manager:machine():popmessage(string.format(_("Activated: %s"), cheat.desc)) + manager.machine:popmessage(string.format(_("Activated: %s"), cheat.desc)) end end end @@ -803,7 +803,7 @@ function cheat.startplugin() start_time = emu.time() cheats = load_cheats() local json = require("json") - local file = io.open(manager:machine():options().entries.cheatpath:value():match("([^;]+)") .. "/output.json", "w") + local file = io.open(manager.machine.options.entries.cheatpath:value():match("([^;]+)") .. "/output.json", "w") if file then file:write(json.stringify(cheats, {indent = true})) file:close() @@ -812,8 +812,8 @@ function cheat.startplugin() parse_cheat(cheat) end load_hotkeys() - if manager:machine():debugger() then - consolelog = manager:machine():debugger().consolelog + if manager.machine.debugger then + consolelog = manager.machine.debugger.consolelog consolelast = 0 end end) @@ -833,22 +833,22 @@ function cheat.startplugin() run_if(cheat, cheat.script.run) end if cheat.hotkeys and cheat.hotkeys.keys then - if manager:machine():input():seq_pressed(cheat.hotkeys.keys) then + if manager.machine.input:seq_pressed(cheat.hotkeys.keys) then if not cheat.hotkeys.pressed then if cheat.is_oneshot then if not run_if(cheat, cheat.script.change) then run_if(cheat, cheat.script.on) end - manager:machine():popmessage(string.format(_("Activated: %s"), cheat.desc)) + manager.machine:popmessage(string.format(_("Activated: %s"), cheat.desc)) elseif not cheat.enabled then cheat.enabled = true run_if(cheat, cheat.script.on) - manager:machine():popmessage(string.format(_("Enabled: %s"), cheat.desc)) + manager.machine:popmessage(string.format(_("Enabled: %s"), cheat.desc)) else cheat.enabled = false run_if(cheat, cheat.script.off) bwpclr(cheat) - manager:machine():popmessage(string.format(_("Disabled: %s"), cheat.desc)) + manager.machine:popmessage(string.format(_("Disabled: %s"), cheat.desc)) end end cheat.hotkeys.pressed = true @@ -858,7 +858,7 @@ function cheat.startplugin() end end for num, input in pairs(inputs) do - local _, screen = next(manager:machine().screens) + local _, screen = next(manager.machine.screens) local framenum = screen:frame_number() - input.begin local enttab = input.start[framenum] if enttab then @@ -907,7 +907,7 @@ function cheat.startplugin() function ce.inject(newcheat) cheats[#cheats + 1] = newcheat parse_cheat(newcheat) - manager:machine():popmessage(string.format(_("%s added"), newcheat.desc)) + manager.machine:popmessage(string.format(_("%s added"), newcheat.desc)) end function ce.get(index) @@ -922,7 +922,7 @@ function cheat.startplugin() is_oneshot = cheat.is_oneshot, comment = cheat.comment, get_hotkeys = function() if cheat.hotkeys then return cheat.hotkeys.keys end return nil end, - set_hotkeys = function(seq) cheat.hotkeys = { pressed = false, keys = manager:machine():input():seq_clean(seq) } end + set_hotkeys = function(seq) cheat.hotkeys = { pressed = false, keys = manager.machine.input:seq_clean(seq) } end } if cheat.script then intf.script = {} diff --git a/plugins/cheatfind/init.lua b/plugins/cheatfind/init.lua index 1a3be72d9bc..9ac4db42e21 100644 --- a/plugins/cheatfind/init.lua +++ b/plugins/cheatfind/init.lua @@ -16,7 +16,7 @@ function cheatfind.startplugin() -- return table of devices and spaces function cheat.getspaces() local spaces = {} - for tag, device in pairs(manager:machine().devices) do + for tag, device in pairs(manager.machine.devices) do if device.spaces then spaces[tag] = {} for name, space in pairs(device.spaces) do @@ -30,7 +30,7 @@ function cheatfind.startplugin() -- return table of ram devices function cheat.getram() local ram = {} - for tag, device in pairs(manager:machine().devices) do + for tag, device in pairs(manager.machine.devices) do if device.shortname == "ram" then ram[tag] = {} ram[tag].dev = device @@ -43,7 +43,7 @@ function cheatfind.startplugin() -- return table of share regions function cheat.getshares() local shares = {} - for tag, share in pairs(manager:machine():memory().shares) do + for tag, share in pairs(manager.machine.memory.shares) do shares[tag] = share end return shares @@ -395,7 +395,7 @@ function cheatfind.startplugin() local r name, r = incdec(event, name, 1, #c) if (event == "select" or event == "comment") and name == 1 then - manager:machine():popmessage(string.format(_("Default name is %s"), cheat_save.name)) + manager.machine:popmessage(string.format(_("Default name is %s"), cheat_save.name)) end return r end @@ -424,7 +424,7 @@ function cheatfind.startplugin() r = true end elseif event == "select" or event == "comment" or event == "right" then - manager:machine():popmessage(_("You can enter any type name")) + manager.machine:popmessage(_("You can enter any type name")) end end return r @@ -441,7 +441,7 @@ function cheatfind.startplugin() if name == 2 then desc = name_type ~= #ctype and ctype[name_type] or name_other if #desc == 0 then - manager:machine():popmessage(_("Type name is empty")) + manager.machine:popmessage(_("Type name is empty")) return end if cplayer[name_player] ~= "All" then @@ -465,7 +465,7 @@ function cheatfind.startplugin() -- old cheat .dat format, write support only (for cheat forum posting of new cheats if posted in simple format) file:write(string.format(cheat_save.dat, desc)) file:close() - manager:machine():popmessage(string.format(_("Cheat written to %s and added to cheat.simple"), filename)) + manager.machine:popmessage(string.format(_("Cheat written to %s and added to cheat.simple"), filename)) end written = true elseif not getmetatable(devtable[devcur].space).__name:match("device_t") and devtable[devcur].sname == "program" then @@ -475,12 +475,12 @@ function cheatfind.startplugin() -- old cheat .dat format, write support only (for cheat forum posting of new cheats if posted in simple format) file:write(string.format(cheat_save.dat, desc)) file:close() - manager:machine():popmessage(_("Cheat added to cheat.simple")) + manager.machine:popmessage(_("Cheat added to cheat.simple")) written = true end end if not written then - manager:machine():popmessage(_("Unable to write file\nEnsure that cheatpath folder exists")) + manager.machine:popmessage(_("Unable to write file\nEnsure that cheatpath folder exists")) end cheat_save = nil return true @@ -498,7 +498,7 @@ function cheatfind.startplugin() menu_lim(devsel, 1, #devtable, m) local function f(event) if (event == "left" or event == "right") and #menu_blocks ~= 0 then - manager:machine():popmessage(_("Changes to this only take effect when \"Start new search\" is selected")) + manager.machine:popmessage(_("Changes to this only take effect when \"Start new search\" is selected")) end devsel = incdec(event, devsel, 1, #devtable) return true @@ -515,10 +515,10 @@ function cheatfind.startplugin() if pausesel == 1 then pausesel = 2 menu_is_showing = false - manager:machine():popmessage(_("Manually toggle pause when needed")) + manager.machine:popmessage(_("Manually toggle pause when needed")) else pausesel = 1 - manager:machine():popmessage(_("Automatically toggle pause with on-screen menus")) + manager.machine:popmessage(_("Automatically toggle pause with on-screen menus")) emu.pause() end end @@ -539,7 +539,7 @@ function cheatfind.startplugin() menu_blocks[num] = {} menu_blocks[num][1] = cheat.save(devtable[devcur].space, region.offset, region.size) end - manager:machine():popmessage(_("All slots cleared and current state saved to Slot 1")) + manager.machine:popmessage(_("All slots cleared and current state saved to Slot 1")) watches = {} opsel = 1 value = 0 @@ -562,7 +562,7 @@ function cheatfind.startplugin() for num, region in ipairs(devtable[devcur].ram) do menu_blocks[num][#menu_blocks[num] + 1] = cheat.save(devtable[devcur].space, region.offset, region.size) end - manager:machine():popmessage(string.format(_("Memory state saved to Slot %d"), #menu_blocks[1])) + manager.machine:popmessage(string.format(_("Memory state saved to Slot %d"), #menu_blocks[1])) if (leftop == #menu_blocks[1] - 1 and rightop == #menu_blocks[1] - 2 ) then leftop = #menu_blocks[1] rightop = #menu_blocks[1]-1 @@ -609,7 +609,7 @@ function cheatfind.startplugin() count = count + #matches[#matches][num] end end - manager:machine():popmessage(string.format(_("%d total matches found"), count)) + manager.machine:popmessage(string.format(_("%d total matches found"), count)) matches[#matches].count = count matchpg = 0 devsel = devcur @@ -672,25 +672,25 @@ function cheatfind.startplugin() opsel, r = incdec(event, opsel, 1, #optable) if event == "left" or event == "right" or event == "comment" then if optable[opsel] == "lt" then - manager:machine():popmessage(_("Left less than right")) + manager.machine:popmessage(_("Left less than right")) elseif optable[opsel] == "gt" then - manager:machine():popmessage(_("Left greater than right")) + manager.machine:popmessage(_("Left greater than right")) elseif optable[opsel] == "eq" then - manager:machine():popmessage(_("Left equal to right")) + manager.machine:popmessage(_("Left equal to right")) elseif optable[opsel] == "ne" then - manager:machine():popmessage(_("Left not equal to right")) + manager.machine:popmessage(_("Left not equal to right")) elseif optable[opsel] == "beq" then - manager:machine():popmessage(_("Left equal to right with bitmask")) + manager.machine:popmessage(_("Left equal to right with bitmask")) elseif optable[opsel] == "bne" then - manager:machine():popmessage(_("Left not equal to right with bitmask")) + manager.machine:popmessage(_("Left not equal to right with bitmask")) elseif optable[opsel] == "ltv" then - manager:machine():popmessage(_("Left less than value")) + manager.machine:popmessage(_("Left less than value")) elseif optable[opsel] == "gtv" then - manager:machine():popmessage(_("Left greater than value")) + manager.machine:popmessage(_("Left greater than value")) elseif optable[opsel] == "eqv" then - manager:machine():popmessage(_("Left equal to value")) + manager.machine:popmessage(_("Left equal to value")) elseif optable[opsel] == "nev" then - manager:machine():popmessage(_("Left not equal to value")) + manager.machine:popmessage(_("Left not equal to value")) end end return r @@ -741,11 +741,11 @@ function cheatfind.startplugin() pokevalsel, r = incdec(event, pokevalsel, 1, #pokevaltable) if event == "left" or event == "right" or event == "comment" then if pokevalsel == 1 then - manager:machine():popmessage(_("Use this if you want to poke the Slot 1 value (eg. You started with something but lost it)")) + manager.machine:popmessage(_("Use this if you want to poke the Slot 1 value (eg. You started with something but lost it)")) elseif pokevalsel == 2 then - manager:machine():popmessage(_("Use this if you want to poke the Last Slot value (eg. You started without an item but finally got it)")) + manager.machine:popmessage(_("Use this if you want to poke the Last Slot value (eg. You started without an item but finally got it)")) else - manager:machine():popmessage(string.format(_("Use this if you want to poke %s"), pokevaltable[pokevalsel])) + manager.machine:popmessage(string.format(_("Use this if you want to poke %s"), pokevaltable[pokevalsel])) end end return r @@ -940,7 +940,7 @@ function cheatfind.startplugin() end if match.mode == 1 then if not emu.plugin.cheat then - manager:machine():popmessage(_("Cheat engine not available")) + manager.machine:popmessage(_("Cheat engine not available")) else emu.plugin.cheat.inject(cheat) end @@ -954,14 +954,14 @@ function cheatfind.startplugin() if emu.softname():find(":") then setname = emu.softname():gsub(":", "/") else - for name, image in pairs(manager:machine().images) do + for name, image in pairs(manager.machine.images) do if image:exists() and image:software_list_name() ~= "" then setname = image:software_list_name() .. "/" .. emu.softname() end end end end - cheat_save.path = emu.subst_env(manager:machine():options().entries.cheatpath:value()):match("([^;]+)") + cheat_save.path = emu.subst_env(manager.machine.options.entries.cheatpath:value()):match("([^;]+)") cheat_save.filename = string.format("%s/%s", cheat_save.path, setname) cheat_save.name = cheat.desc local json = require("json") @@ -970,7 +970,7 @@ function cheatfind.startplugin() cheat_save.xml = string.format("<mamecheat version=\"1\">\n <cheat desc=\"%%s\">\n <script state=\"run\">\n <action>%s.pp%s@%X=%X</action>\n </script>\n </cheat>\n</mamecheat>", dev.tag:sub(2), widchar, match.addr, match.newval) cheat_save.simple = string.format("%s,%s,%X,%s,%X,%%s\n", setname, dev.tag, match.addr, widchar, pokevalue) cheat_save.dat = string.format(":%s:40000000:%X:%08X:FFFFFFFF:%%s\n", setname, match.addr, pokevalue) - manager:machine():popmessage(string.format(_("Default name is %s"), cheat_save.name)) + manager.machine:popmessage(string.format(_("Default name is %s"), cheat_save.name)) return true else local func = "return space:read" @@ -1045,19 +1045,19 @@ function cheatfind.startplugin() end emu.register_menu(menu_callback, menu_populate, _("Cheat Finder")) emu.register_frame_done(function () - local screen = manager:machine().screens:at(1) - local height = mame_manager:ui():get_line_height() + local screen = manager.machine.screens:at(1) + local height = mame_manager.ui.line_height for num, watch in ipairs(watches) do screen:draw_text("left", num * height, string.format(watch.format, watch.addr, watch.func())) end - if tabbed_out and manager:ui():is_menu_active() then + if tabbed_out and manager.ui.menu_active then emu.pause() menu_is_showing = true tabbed_out = false end end) emu.register_periodic(function () - if menu_is_showing and not manager:ui():is_menu_active() then + if menu_is_showing and not manager.ui.menu_active then emu.unpause() menu_is_showing = false tabbed_out = true diff --git a/plugins/console/init.lua b/plugins/console/init.lua index af8a8b7965d..330d445fedb 100644 --- a/plugins/console/init.lua +++ b/plugins/console/init.lua @@ -216,8 +216,8 @@ return ln.linenoise('$PROMPT') end emu.register_start(function() - if not consolebuf and manager:machine():debugger() then - consolebuf = manager:machine():debugger().consolelog + if not consolebuf and manager.machine.debugger then + consolebuf = manager.machine.debugger.consolelog lastindex = 0 end end) diff --git a/plugins/data/data_hiscore.lua b/plugins/data/data_hiscore.lua index 867041a14cc..ac2513d2690 100644 --- a/plugins/data/data_hiscore.lua +++ b/plugins/data/data_hiscore.lua @@ -9,7 +9,7 @@ local curset function env.open(file, size) if file == ".hi" then local path = "hi" - local ini = emu.file(emu.subst_env(manager:options().entries.inipath:value()), 1) + local ini = emu.file(emu.subst_env(manager.options.entries.inipath:value()), 1) local ret = ini:open("hiscore.ini") if not ret then local inifile = ini:read(ini:size()) @@ -23,7 +23,7 @@ function env.open(file, size) end file = path .. "/" .. curset .. ".hi" else - file = emu.subst_env(manager:options().entries.nvram_directory:value()) .. "/" .. curset .. "/" .. file + file = emu.subst_env(manager.options.entries.nvram_directory:value()) .. "/" .. curset .. "/" .. file end local f = io.open(file, "rb") local content = f:read("*all") @@ -789,12 +789,12 @@ function dat.check(set, softlist) output = nil curset = set - local scrfile = emu.file(emu.subst_env(mame_manager:ui():options().entries.historypath:value():gsub("([^;]+)", "%1/hi2txt")), 1) + local scrfile = emu.file(emu.subst_env(mame_manager.ui.options.entries.historypath:value():gsub("([^;]+)", "%1/hi2txt")), 1) local ret = scrfile:open(set .. ".lua") local script if ret then function get_xml_table(fileset) - local file = emu.file(emu.subst_env(mame_manager:ui():options().entries.historypath:value():gsub("([^;]+)", "%1/hi2txt")), 1) + local file = emu.file(emu.subst_env(mame_manager.ui.options.entries.historypath:value():gsub("([^;]+)", "%1/hi2txt")), 1) local ret = file:open(fileset .. ".xml") if ret then return nil diff --git a/plugins/data/data_marp.lua b/plugins/data/data_marp.lua index 5cb0bc3fb19..98e6e8160d4 100644 --- a/plugins/data/data_marp.lua +++ b/plugins/data/data_marp.lua @@ -9,7 +9,7 @@ local function init() local fh local file = "scores3.htm" - for path in mame_manager:ui():options().entries.historypath:value():gmatch("([^;]+)") do + for path in mame_manager.ui.options.entries.historypath:value():gmatch("([^;]+)") do filepath = emu.subst_env(path) .. "/" .. file fh = io.open(filepath, "r") if fh then diff --git a/plugins/data/database.lua b/plugins/data/database.lua index da1a2508cad..b868173ce08 100644 --- a/plugins/data/database.lua +++ b/plugins/data/database.lua @@ -4,12 +4,12 @@ local db local function check_db(msg) if db:errcode() > sql.OK then - emu.print_error("Error: " .. msg .. " (" .. db:errcode() .. " - " .. db:errmsg() .. ")\n") + emu.print_error(string.format("Error: %s (%s - %s)\n", msg, db:errcode(), db:errmsg())) end end do - local dbpath = emu.subst_env(mame_manager:ui():options().entries.historypath:value():match("([^;]+)")) + local dbpath = emu.subst_env(mame_manager.ui.options.entries.historypath:value():match("([^;]+)")) db = sql.open(dbpath .. "/history.db") if not db then lfs.mkdir(dbpath) diff --git a/plugins/data/load_dat.lua b/plugins/data/load_dat.lua index a21ae51aebe..ed13fbefdcc 100644 --- a/plugins/data/load_dat.lua +++ b/plugins/data/load_dat.lua @@ -26,7 +26,7 @@ function datfile.open(file, vertag, fixupcb) local filepath local fh - for path in mame_manager:ui():options().entries.historypath:value():gmatch("([^;]+)") do + for path in mame_manager.ui.options.entries.historypath:value():gmatch("([^;]+)") do filepath = emu.subst_env(path) .. "/" .. file fh = io.open(filepath, "r") if fh then diff --git a/plugins/discord/init.lua b/plugins/discord/init.lua index 5e5ce88a514..83ac15d18b0 100644 --- a/plugins/discord/init.lua +++ b/plugins/discord/init.lua @@ -49,9 +49,9 @@ function discord.startplugin() if not pipe then return end local running = emu.romname() ~= "___empty" local state = not running and "In menu" or status - local details = running and manager:machine():system().description or nil + local details = running and manager.machine.system.description or nil if emu.softname() ~= "" then - for name, dev in pairs(manager:machine().images) do + for name, dev in pairs(manager.machine.images) do if dev:longname() then details = details .. " (" .. dev:longname() .. ")" break diff --git a/plugins/gdbstub/init.lua b/plugins/gdbstub/init.lua index afc5428dd22..f7d4ceee6ba 100644 --- a/plugins/gdbstub/init.lua +++ b/plugins/gdbstub/init.lua @@ -36,12 +36,12 @@ function gdbstub.startplugin() local running emu.register_start(function () - debugger = manager:machine():debugger() + debugger = manager.machine.debugger if not debugger then print("gdbstub: debugger not enabled") return end - cpu = manager:machine().devices[":maincpu"] + cpu = manager.machine.devices[":maincpu"] if not cpu then print("gdbstub: maincpu not found") end diff --git a/plugins/hiscore/init.lua b/plugins/hiscore/init.lua index e4da7cda4d6..2a9687d1547 100644 --- a/plugins/hiscore/init.lua +++ b/plugins/hiscore/init.lua @@ -23,7 +23,7 @@ function hiscore.startplugin() local hiscoredata_path = "hiscore.dat"; local hiscore_path = "hi"; - local config_path = emu.subst_env(manager:options().entries.inipath:value():match("[^;]+") .. "/hiscore.ini"); + local config_path = emu.subst_env(manager.options.entries.inipath:value():match("[^;]+") .. "/hiscore.ini"); local current_checksum = 0; local default_checksum = 0; @@ -68,13 +68,13 @@ function hiscore.startplugin() else local cpu, mem; local cputag, space, offs, len, chk_st, chk_ed, fill = string.match(line, '^@([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),?(%x?%x?)'); - cpu = manager:machine().devices[cputag]; + cpu = manager.machine.devices[cputag]; if not cpu then error(cputag .. " device not found") end local rgnname, rgntype = space:match("([^/]*)/?([^/]*)") if rgntype == "share" then - mem = manager:machine():memory().shares[rgnname] + mem = manager.machine.memory.shares[rgnname] else mem = cpu.spaces[space] end diff --git a/plugins/layout/init.lua b/plugins/layout/init.lua index 654df599bd3..55cb433baf2 100644 --- a/plugins/layout/init.lua +++ b/plugins/layout/init.lua @@ -15,7 +15,7 @@ function layout.startplugin() local scripts = {} local function prepare_layout(file, script) local env = { - machine = manager:machine(), + machine = manager.machine, emu = { render_bounds = emu.render_bounds, render_color = emu.render_color, @@ -42,7 +42,7 @@ function layout.startplugin() emu.register_callback(prepare_layout, "layout") emu.register_frame(function() - if manager:machine().paused then + if manager.machine.paused then return end for num, scr in pairs(scripts) do diff --git a/plugins/portname/init.lua b/plugins/portname/init.lua index 78e8da626b0..7103f138e76 100644 --- a/plugins/portname/init.lua +++ b/plugins/portname/init.lua @@ -28,7 +28,7 @@ local portname = exports function portname.startplugin() local json = require("json") - local ctrlrpath = emu.subst_env(manager:options().entries.ctrlrpath:value():match("([^;]+)")) + local ctrlrpath = emu.subst_env(manager.options.entries.ctrlrpath:value():match("([^;]+)")) local function get_filename(nosoft) local filename if emu.softname() ~= "" and not nosoft then @@ -56,7 +56,7 @@ function portname.startplugin() return end for pname, port in pairs(ctable.ports) do - local ioport = manager:machine():ioport().ports[pname] + local ioport = manager.machine.ioport.ports[pname] if ioport then for mask, label in pairs(port.labels) do for num3, field in pairs(ioport.fields) do @@ -76,7 +76,7 @@ function portname.startplugin() if ret then if emu.softname() ~= "" then local parent - for tag, image in pairs(manager:machine().images) do + for tag, image in pairs(manager.machine.images) do parent = image.software_parent if parent ~= "" then break @@ -89,7 +89,7 @@ function portname.startplugin() if ret then ret = file:open(get_filename(true)) if ret then - ret = file:open(manager:machine():system().parent .. ".json") + ret = file:open(manager.machine.system.parent .. ".json") if ret then return end @@ -106,7 +106,7 @@ function portname.startplugin() local function menu_callback(index, event) if event == "select" then local ports = {} - for pname, port in pairs(manager:machine():ioport().ports) do + for pname, port in pairs(manager.machine.ioport.ports) do local labels = {} local sort = {} for fname, field in pairs(port.fields) do @@ -131,12 +131,12 @@ function portname.startplugin() if not attr then lfs.mkdir(path) if not lfs.attributes(path) then - manager:machine():popmessage(_("Failed to save input name file")) + manager.machine:popmessage(_("Failed to save input name file")) emu.print_verbose("portname: unable to create path " .. path .. "\n") return false end elseif attr.mode ~= "directory" then - manager:machine():popmessage(_("Failed to save input name file")) + manager.machine:popmessage(_("Failed to save input name file")) emu.print_verbose("portname: path exists but isn't directory " .. path .. "\n") return false end @@ -152,7 +152,7 @@ function portname.startplugin() local file = io.open(ctrlrpath .. "/portname/" .. filename, "r") if file then emu.print_verbose("portname: input name file exists " .. filename .. "\n") - manager:machine():popmessage(_("Failed to save input name file")) + manager.machine:popmessage(_("Failed to save input name file")) file:close() return false end @@ -164,7 +164,7 @@ function portname.startplugin() setmetatable(ctable, { __jsonorder = { "romname", "softname", "ports" }}) file:write(json.stringify(ctable, { indent = true })) file:close() - manager:machine():popmessage(string.format(_("Input port name file saved to %s"), ctrlrpath .. "/portname/" .. filename)) + manager.machine:popmessage(string.format(_("Input port name file saved to %s"), ctrlrpath .. "/portname/" .. filename)) end return false end diff --git a/plugins/timer/init.lua b/plugins/timer/init.lua index 95601ac67f3..f0ddabbcf50 100644 --- a/plugins/timer/init.lua +++ b/plugins/timer/init.lua @@ -12,7 +12,7 @@ exports.author = { name = "Carl" } local timer = exports function timer.startplugin() - local dir = emu.subst_env(manager:options().entries.homepath:value()) + local dir = emu.subst_env(manager.options.entries.homepath:value()) local timer_db = dir .. "/timer/timer.db" local timer_started = false local total_time = 0 diff --git a/src/devices/sound/disc_cls.h b/src/devices/sound/disc_cls.h index cb043557734..5761b31ae9e 100644 --- a/src/devices/sound/disc_cls.h +++ b/src/devices/sound/disc_cls.h @@ -5,6 +5,8 @@ #pragma once +#include "wavwrite.h" + /*********************************************************************** * * MAME - Discrete sound system emulation library @@ -130,12 +132,12 @@ private: DISCRETE_CLASS(dso_csvlog, 0, FILE *m_csv_file; int64_t m_sample_num; - char m_name[32]; + char m_name[32]; ); DISCRETE_CLASS(dso_wavlog, 0, - wav_file *m_wavfile; - char m_name[32]; + util::wav_file_ptr m_wavfile; + char m_name[32]; ); /************************************* diff --git a/src/devices/sound/disc_sys.hxx b/src/devices/sound/disc_sys.hxx index 539942a707b..86cb356ec38 100644 --- a/src/devices/sound/disc_sys.hxx +++ b/src/devices/sound/disc_sys.hxx @@ -81,14 +81,13 @@ DISCRETE_START( dso_wavlog ) log_num = m_device->same_module_index(*this); sprintf(m_name, "%s_%d.csv", m_device->basetag(), log_num); - m_wavfile = wav_open(m_name, sample_rate(), active_inputs()/2); + m_wavfile = util::wav_open(m_name, sample_rate(), active_inputs()/2); } DISCRETE_STOP( dso_wavlog ) { /* close any wave files */ - if (m_wavfile) - wav_close(m_wavfile); + m_wavfile.reset(); } DISCRETE_STEP( dso_wavlog ) @@ -104,7 +103,7 @@ DISCRETE_STEP( dso_wavlog ) if (this->active_inputs() == 2) { /* DISCRETE_WAVLOG1 */ - wav_add_data_16(m_wavfile, &wave_data_l, 1); + util::wav_add_data_16(*m_wavfile, &wave_data_l, 1); } else { @@ -113,7 +112,7 @@ DISCRETE_STEP( dso_wavlog ) val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; wave_data_r = (int16_t)val; - wav_add_data_16lr(m_wavfile, &wave_data_l, &wave_data_r, 1); + util::wav_add_data_16lr(*m_wavfile, &wave_data_l, &wave_data_r, 1); } } diff --git a/src/devices/sound/gaelco.cpp b/src/devices/sound/gaelco.cpp index 2a213408095..7da4ab16f76 100644 --- a/src/devices/sound/gaelco.cpp +++ b/src/devices/sound/gaelco.cpp @@ -37,6 +37,7 @@ Registers per channel: #include "emu.h" #include "gaelco.h" + #include "wavwrite.h" #define VERBOSE_SOUND 0 @@ -47,7 +48,7 @@ Registers per channel: //#define ALT_MIX #define LOG_WAVE 0 -static wav_file* wavraw; // Raw waveform +static util::wav_file_ptr wavraw; // Raw waveform /*============================================================================ @@ -182,7 +183,7 @@ void gaelco_gae1_device::sound_stream_update(sound_stream &stream, std::vector<r } // if (wavraw) -// wav_add_data_buffer(wavraw, outputs[0], outputs[1]); +// util::wav_add_data_buffer(*wavraw, outputs[0], outputs[1]); } /*============================================================================ @@ -261,15 +262,13 @@ void gaelco_gae1_device::device_start() m_volume_table[vol][(j ^ 0x80) & 0xff] = (vol*j*256)/(VOLUME_LEVELS - 1); if (LOG_WAVE) - wavraw = wav_open("gae1_snd.wav", rate, 2); + wavraw = util::wav_open("gae1_snd.wav", rate, 2); } void gaelco_gae1_device::device_stop() { - if (wavraw) - wav_close(wavraw); - wavraw = nullptr; + wavraw.reset(); } @@ -283,11 +282,10 @@ void gaelco_gae1_device::device_clock_changed() { u32 rate = clock() / 128; m_stream->set_sample_rate(rate); - if (wavraw) - wav_close(wavraw); + wavraw.reset(); if (LOG_WAVE) - wavraw = wav_open("gae1_snd.wav", rate, 2); + wavraw = util::wav_open("gae1_snd.wav", rate, 2); } diff --git a/src/devices/sound/k007232.cpp b/src/devices/sound/k007232.cpp index de6c2cdb4ec..32623f187df 100644 --- a/src/devices/sound/k007232.cpp +++ b/src/devices/sound/k007232.cpp @@ -223,17 +223,16 @@ void k007232_device::sound_stream_update(sound_stream &stream, std::vector<read_ { char filebuf[256]; snprintf(filebuf, 256, "pcm%08x.wav", channel->start); - wav_file *file = wav_open(filebuf, stream.sample_rate(), 1); - if (file != nullptr) + util::wav_file_ptr file = util::wav_open(filebuf, stream.sample_rate(), 1); + if (file) { u32 addr = channel->start; while (!BIT(read_sample(i, addr), 7) && addr < m_pcmlimit) { int16_t out = ((read_sample(i, addr) & 0x7f) - 0x40) << 7; - wav_add_data_16(file, &out, 1); + util::wav_add_data_16(*file, &out, 1); addr++; } - wav_close(file); } } } diff --git a/src/devices/sound/sn76477.cpp b/src/devices/sound/sn76477.cpp index b8db037e26b..1ccbd2fc4b5 100644 --- a/src/devices/sound/sn76477.cpp +++ b/src/devices/sound/sn76477.cpp @@ -895,9 +895,9 @@ void sn76477_device::open_wav_file() std::string s = tag(); std::replace(s.begin(), s.end(), ':', '_'); - const std::string wav_file_name = util::string_format(LOG_WAV_FILE_NAME, s).c_str(); + const std::string wav_file_name = util::string_format(LOG_WAV_FILE_NAME, s); - m_file = wav_open(wav_file_name.c_str(), m_our_sample_rate, 2); + m_file = util::wav_open(wav_file_name, m_our_sample_rate, 2); LOG(1, "SN76477: Logging output: %s\n", wav_file_name); } @@ -905,13 +905,13 @@ void sn76477_device::open_wav_file() void sn76477_device::close_wav_file() { - wav_close(m_file); + m_file.reset(); } void sn76477_device::add_wav_data(int16_t data_l, int16_t data_r) { - wav_add_data_16lr(m_file, &data_l, &data_r, 1); + util::wav_add_data_16lr(*m_file, &data_l, &data_r, 1); } diff --git a/src/devices/sound/sn76477.h b/src/devices/sound/sn76477.h index 094f8e78e1b..6aa4c10c9f0 100644 --- a/src/devices/sound/sn76477.h +++ b/src/devices/sound/sn76477.h @@ -42,6 +42,8 @@ #include "machine/rescap.h" +#include "wavwrite.h" + /***************************************************************************** * @@ -186,24 +188,24 @@ private: double m_pitch_voltage; // internal state - double m_one_shot_cap_voltage; /* voltage on the one-shot cap */ - uint32_t m_one_shot_running_ff; /* 1 = one-shot running, 0 = stopped */ + double m_one_shot_cap_voltage; // voltage on the one-shot cap + uint32_t m_one_shot_running_ff; // 1 = one-shot running, 0 = stopped - double m_slf_cap_voltage; /* voltage on the SLF cap */ - uint32_t m_slf_out_ff; /* output of the SLF */ + double m_slf_cap_voltage; // voltage on the SLF cap + uint32_t m_slf_out_ff; // output of the SLF - double m_vco_cap_voltage; /* voltage on the VCO cap */ - uint32_t m_vco_out_ff; /* output of the VCO */ - uint32_t m_vco_alt_pos_edge_ff; /* keeps track of the # of positive edges for VCO Alt envelope */ + double m_vco_cap_voltage; // voltage on the VCO cap + uint32_t m_vco_out_ff; // output of the VCO + uint32_t m_vco_alt_pos_edge_ff; // keeps track of the # of positive edges for VCO Alt envelope - double m_noise_filter_cap_voltage; /* voltage on the noise filter cap */ - uint32_t m_real_noise_bit_ff; /* the current noise bit before filtering */ - uint32_t m_filtered_noise_bit_ff; /* the noise bit after filtering */ - uint32_t m_noise_gen_count; /* noise freq emulation */ + double m_noise_filter_cap_voltage; // voltage on the noise filter cap + uint32_t m_real_noise_bit_ff; // the current noise bit before filtering + uint32_t m_filtered_noise_bit_ff; // the noise bit after filtering + uint32_t m_noise_gen_count; // noise freq emulation - double m_attack_decay_cap_voltage; /* voltage on the attack/decay cap */ + double m_attack_decay_cap_voltage; // voltage on the attack/decay cap - uint32_t m_rng; /* current value of the random number generator */ + uint32_t m_rng; // current value of the random number generator // configured by the drivers and used to setup m_mixer_mode & m_envelope_mode at start uint32_t m_mixer_a; @@ -213,10 +215,10 @@ private: uint32_t m_envelope_2; /* others */ - sound_stream *m_channel; /* returned by stream_create() */ - int m_our_sample_rate; /* from machine.sample_rate() */ + sound_stream *m_channel; // returned by stream_create() + int m_our_sample_rate; // from machine.sample_rate() - wav_file *m_file; /* handle of the wave file to produce */ + util::wav_file_ptr m_file; // handle of the wave file to produce double compute_one_shot_cap_charging_rate(); double compute_one_shot_cap_discharging_rate(); diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h index aa8b72b8d9c..8d47e42829a 100644 --- a/src/emu/emufwd.h +++ b/src/emu/emufwd.h @@ -52,9 +52,6 @@ class chd_file; // declared in unzip.h namespace util { class archive_file; } -// declared in wavwrite.h -struct wav_file; - // declared in xmlfile.h namespace util::xml { class data_node; } diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp index f25d236083a..3d9b6c428a2 100644 --- a/src/emu/machine.cpp +++ b/src/emu/machine.cpp @@ -984,10 +984,14 @@ void running_machine::handle_saveload() file.remove_on_close(); } else if (openflags == OPEN_FLAG_READ && filerr == osd_file::error::NOT_FOUND) + { // attempt to load a non-existent savestate, report empty slot popmessage("Error: No savestate file to load.", opname); + } else + { popmessage("Error: Failed to open file for %s operation.", opname); + } } } diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index 252c7fc469a..625f0e989e6 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -68,11 +68,8 @@ stream_buffer::stream_buffer(u32 sample_rate) : stream_buffer::~stream_buffer() { #if (SOUND_DEBUG) - if (m_wav_file != nullptr) - { + if (m_wav_file) flush_wav(); - close_wav(); - } #endif } @@ -184,7 +181,7 @@ void stream_buffer::open_wav(char const *filename) { // always open at 48k so that sound programs can handle it // re-sample as needed - m_wav_file = wav_open(filename, 48000, 1); + m_wav_file = util::wav_open(filename, 48000, 1); } #endif @@ -197,7 +194,7 @@ void stream_buffer::open_wav(char const *filename) void stream_buffer::flush_wav() { // skip if no file - if (m_wav_file == nullptr) + if (!m_wav_file) return; // grab a view of the data from the last-written point @@ -218,27 +215,13 @@ void stream_buffer::flush_wav() buffer[sampindex] = s16(view.get(samplebase + sampindex) * 32768.0); // write to the WAV - wav_add_data_16(m_wav_file, buffer, cursamples); + util::wav_add_data_16(*m_wav_file, buffer, cursamples); } } #endif //------------------------------------------------- -// close_wav - close the logging WAV file -//------------------------------------------------- - -#if (SOUND_DEBUG) -void stream_buffer::close_wav() -{ - if (m_wav_file != nullptr) - wav_close(m_wav_file); - m_wav_file = nullptr; -} -#endif - - -//------------------------------------------------- // index_time - return the attotime of a given // index within the buffer //------------------------------------------------- @@ -1089,7 +1072,7 @@ sound_manager::sound_manager(running_machine &machine) : m_nosound_mode(machine.osd().no_sound()), m_attenuation(0), m_unique_id(0), - m_wavfile(nullptr), + m_wavfile(), m_first_reset(true) { // get filename for WAV file or AVI file if specified @@ -1156,12 +1139,19 @@ sound_stream *sound_manager::stream_alloc(device_t &device, u32 inputs, u32 outp // start_recording - begin audio recording //------------------------------------------------- -void sound_manager::start_recording() +bool sound_manager::start_recording(std::string_view filename) +{ + if (m_wavfile) + return false; + m_wavfile = util::wav_open(filename, machine().sample_rate(), 2); + return bool(m_wavfile); +} + +bool sound_manager::start_recording() { // open the output WAV file if specified - const char *wavfile = machine().options().wav_write(); - if (wavfile[0] != 0 && m_wavfile == nullptr) - m_wavfile = wav_open(wavfile, machine().sample_rate(), 2); + char const *const filename = machine().options().wav_write(); + return *filename ? start_recording(filename) : false; } @@ -1172,9 +1162,7 @@ void sound_manager::start_recording() void sound_manager::stop_recording() { // close any open WAV file - if (m_wavfile != nullptr) - wav_close(m_wavfile); - m_wavfile = nullptr; + m_wavfile.reset(); } @@ -1311,9 +1299,11 @@ void sound_manager::reset() for (speaker_device &speaker : speaker_device_enumerator(machine().root_device())) { int dummy; - sound_stream *output = speaker.output_to_stream_output(0, dummy); - if (output != nullptr) + sound_stream *const output = speaker.output_to_stream_output(0, dummy); + if (output) recursive_remove_stream_from_orphan_list(output); + + m_speakers.emplace_back(speaker); } #if (SOUND_DEBUG) @@ -1487,7 +1477,7 @@ void sound_manager::update(void *ptr, int param) std::fill_n(&m_rightmix[0], m_samples_this_update, 0); // force all the speaker streams to generate the proper number of samples - for (speaker_device &speaker : speaker_device_enumerator(machine().root_device())) + for (speaker_device &speaker : m_speakers) speaker.mix(&m_leftmix[0], &m_rightmix[0], m_last_update, endtime, m_samples_this_update, (m_muted & MUTE_REASON_SYSTEM)); // determine the maximum in this section @@ -1582,8 +1572,8 @@ void sound_manager::update(void *ptr, int param) machine().osd().update_audio_stream(finalmix, finalmix_offset / 2); machine().osd().add_audio_to_recording(finalmix, finalmix_offset / 2); machine().video().add_sound_to_recording(finalmix, finalmix_offset / 2); - if (m_wavfile != nullptr) - wav_add_data_16(m_wavfile, finalmix, finalmix_offset); + if (m_wavfile) + util::wav_add_data_16(*m_wavfile, finalmix, finalmix_offset); } // update any orphaned streams so they don't get too far behind diff --git a/src/emu/sound.h b/src/emu/sound.h index 25944847565..de4d2f896a0 100644 --- a/src/emu/sound.h +++ b/src/emu/sound.h @@ -61,6 +61,8 @@ #ifndef MAME_EMU_SOUND_H #define MAME_EMU_SOUND_H +#include "wavwrite.h" + //************************************************************************** // CONSTANTS @@ -209,11 +211,10 @@ public: // for debugging, provide an interface to write a WAV stream void open_wav(char const *filename); void flush_wav(); - void close_wav(); private: // internal debugging state - wav_file *m_wav_file = nullptr; // pointer to the current WAV file + util::wav_file_ptr m_wav_file; // pointer to the current WAV file u32 m_last_written = 0; // last written sample index #endif }; @@ -767,20 +768,23 @@ public: // allocate a new stream with a new-style callback sound_stream *stream_alloc(device_t &device, u32 inputs, u32 outputs, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags); - // begin recording a WAV file if options has requested it - void start_recording(); - - // stop recording the WAV file + // WAV recording + bool is_recording() const { return bool(m_wavfile); } + bool start_recording(); + bool start_recording(std::string_view filename); void stop_recording(); // set the global OSD attenuation level void set_attenuation(float attenuation); // mute sound for one of various independent reasons - void ui_mute(bool turn_off = true) { mute(turn_off, MUTE_REASON_UI); } - void debugger_mute(bool turn_off = true) { mute(turn_off, MUTE_REASON_DEBUGGER); } - void system_mute(bool turn_off = true) { mute(turn_off, MUTE_REASON_SYSTEM); } - void system_enable(bool turn_on = true) { mute(!turn_on, MUTE_REASON_SYSTEM); } + bool muted() const { return bool(m_muted); } + bool ui_mute() const { return bool(m_muted & MUTE_REASON_UI); } + bool debugger_mute() const { return bool(m_muted & MUTE_REASON_DEBUGGER); } + bool system_mute() const { return bool(m_muted & MUTE_REASON_SYSTEM); } + void ui_mute(bool turn_off) { mute(turn_off, MUTE_REASON_UI); } + void debugger_mute(bool turn_off) { mute(turn_off, MUTE_REASON_DEBUGGER); } + void system_mute(bool turn_off) { mute(turn_off, MUTE_REASON_SYSTEM); } // return information about the given mixer input, by index bool indexed_mixer_input(int index, mixer_input &info) const; @@ -818,6 +822,7 @@ private: // internal state running_machine &m_machine; // reference to the running machine emu_timer *m_update_timer; // timer that runs the update function + std::vector<std::reference_wrapper<speaker_device> > m_speakers; u32 m_update_number; // current update index; used for sample rate updates attotime m_last_update; // time of the last update @@ -834,7 +839,7 @@ private: bool m_nosound_mode; // true if we're in "nosound" mode int m_attenuation; // current attentuation level (at the OSD) int m_unique_id; // unique ID used for stream identification - wav_file *m_wavfile; // WAV file for streaming + util::wav_file_ptr m_wavfile; // WAV file for streaming // streams data std::vector<std::unique_ptr<sound_stream>> m_stream_list; // list of streams diff --git a/src/emu/video.cpp b/src/emu/video.cpp index 41275c94dcb..749e9113464 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -185,18 +185,18 @@ video_manager::video_manager(running_machine &machine) void video_manager::set_frameskip(int frameskip) { - // -1 means autoframeskip - if (frameskip == -1) + if (0 > frameskip) { + // -1 means autoframeskip + if (!m_auto_frameskip) + m_frameskip_level = 0; m_auto_frameskip = true; - m_frameskip_level = 0; } - - // any other level is a direct control - else if (frameskip >= 0 && frameskip <= MAX_FRAMESKIP) + else { + // any other level is a direct control m_auto_frameskip = false; - m_frameskip_level = frameskip; + m_frameskip_level = std::min<int>(frameskip, MAX_FRAMESKIP); } } @@ -247,17 +247,19 @@ void video_manager::frame_update(bool from_debugger) emulator_info::periodic_check(); - // perform tasks for this frame if (!from_debugger) + { + // perform tasks for this frame machine().call_notifiers(MACHINE_NOTIFY_FRAME); - // update frameskipping - if (!from_debugger && phase > machine_phase::INIT) - update_frameskip(); + // update frameskipping + if (phase > machine_phase::INIT) + update_frameskip(); - // update speed computations - if (!from_debugger && !skipped_it && phase > machine_phase::INIT) - recompute_speed(current_time); + // update speed computations + if (!skipped_it && phase > machine_phase::INIT) + recompute_speed(current_time); + } // call the end-of-frame callback if (phase == machine_phase::RUNNING) @@ -708,17 +710,6 @@ void video_manager::update_throttle(attotime emutime) restoring from a saved state */ - static const u8 popcount[256] = - { - 0,1,1,2,1,2,2,3, 1,2,2,3,2,3,3,4, 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, - 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, - 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, - 1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, - 2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6, 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7, 5,6,6,7,6,7,7,8 - }; // outer scope so we can break out in case of a resync while (1) @@ -791,7 +782,7 @@ void video_manager::update_throttle(attotime emutime) // if we're more than 1/10th of a second out, or if we are behind at all and emulation // is taking longer than the real frame, we just need to resync if (real_is_ahead_attoseconds < -ATTOSECONDS_PER_SECOND / 10 || - (real_is_ahead_attoseconds < 0 && popcount[m_throttle_history & 0xff] < 6)) + (real_is_ahead_attoseconds < 0 && population_count_32(m_throttle_history & 0xff) < 6)) { if (LOG_THROTTLE) machine().logerror("Resync due to being behind: %s (history=%08X)\n", attotime(0, -real_is_ahead_attoseconds).as_string(18), m_throttle_history); @@ -883,12 +874,12 @@ void video_manager::update_frameskip() if (effective_throttle() && effective_autoframeskip() && m_frameskip_counter == 0) { // calibrate the "adjusted speed" based on the target - double adjusted_speed_percent = m_speed_percent / (double) m_throttle_rate; + double adjusted_speed_percent = m_speed_percent / double(m_throttle_rate); - // if we're too fast, attempt to decrease the frameskip double speed = m_speed * 0.001; if (adjusted_speed_percent >= 0.995 * speed) { + // if we're too fast, attempt to decrease the frameskip // but only after 3 consecutive frames where we are too fast if (++m_frameskip_adjust >= 3) { @@ -897,16 +888,12 @@ void video_manager::update_frameskip() m_frameskip_level--; } } - - // if we're too slow, attempt to increase the frameskip else { - // if below 80% speed, be more aggressive - if (adjusted_speed_percent < 0.80 * speed) + // if we're too slow, attempt to increase the frameskip + if (adjusted_speed_percent < 0.80 * speed) // if below 80% speed, be more aggressive m_frameskip_adjust -= (0.90 * speed - m_speed_percent) / 0.05; - - // if we're close, only force it up to frameskip 8 - else if (m_frameskip_level < 8) + else if (m_frameskip_level < 8) // if we're close, only force it up to frameskip 8 m_frameskip_adjust--; // perform the adjustment @@ -1042,7 +1029,7 @@ typedef software_renderer<u32, 0,0,0, 16,8,0, false, false> snap_renderer; void video_manager::create_snapshot_bitmap(screen_device *screen) { // select the appropriate view in our dummy target - if (m_snap_native && screen != nullptr) + if (m_snap_native && screen) { screen_device_enumerator iter(machine().root_device()); int view_index = iter.indexof(*screen); @@ -1050,14 +1037,12 @@ void video_manager::create_snapshot_bitmap(screen_device *screen) m_snap_target->set_view(view_index); } - // get the minimum width/height and set it on the target + // get the minimum width/height and set it on the target and bitmap s32 width, height; compute_snapshot_size(width, height); m_snap_target->set_bounds(width, height); - - // if we don't have a bitmap, or if it's not the right size, allocate a new one - if (!m_snap_bitmap.valid() || width != m_snap_bitmap.width() || height != m_snap_bitmap.height()) - m_snap_bitmap.allocate(width, height); + if (width != m_snap_bitmap.width() || height != m_snap_bitmap.height()) + m_snap_bitmap.resize(width, height); // render the screen there render_primitive_list &primlist = m_snap_target->get_primitives(); @@ -1266,15 +1251,6 @@ void video_manager::record_frame() g_profiler.stop(); } -//------------------------------------------------- -// toggle_throttle -//------------------------------------------------- - -void video_manager::toggle_throttle() -{ - set_throttled(!throttled()); -} - //------------------------------------------------- // toggle_record_movie diff --git a/src/emu/video.h b/src/emu/video.h index 84654ed01ff..bd58db9ca1d 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -54,13 +54,12 @@ public: // setters void set_frameskip(int frameskip); - void set_throttled(bool throttled = true) { m_throttled = throttled; } + void set_throttled(bool throttled) { m_throttled = throttled; } void set_throttle_rate(float throttle_rate) { m_throttle_rate = throttle_rate; } - void set_fastforward(bool ffwd = true) { m_fastforward = ffwd; } + void set_fastforward(bool ffwd) { m_fastforward = ffwd; } void set_output_changed() { m_output_changed = true; } // misc - void toggle_throttle(); void toggle_record_movie(movie_recording::format format); osd_file::error open_next(emu_file &file, const char *extension, uint32_t index = 0); void compute_snapshot_size(s32 &width, s32 &height); diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 98f00a219d0..fe534302f9e 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -125,6 +125,18 @@ struct image_interface_formats device_image_interface ℑ }; + +struct plugin_options_plugins +{ + plugin_options_plugins(plugin_options &o) : options(o) { } + std::list<plugin_options::plugin> &items() { return options.plugins(); } + + static plugin_options::plugin const &unwrap(std::list<plugin_options::plugin>::const_iterator const &it) { return *it; } + static int push_key(lua_State *L, std::list<plugin_options::plugin>::const_iterator const &it, std::size_t ix) { return sol::stack::push_reference(L, it->m_name); } + + plugin_options &options; +}; + } // anonymous namespace @@ -132,6 +144,7 @@ namespace sol { template <> struct is_container<image_interface_formats> : std::true_type { }; +template <> struct is_container<plugin_options_plugins> : std::true_type { }; sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking) @@ -145,6 +158,7 @@ int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value) return 1; } + template <typename T> struct usertype_container<lua_engine::devenum<T> > : lua_engine::immutable_collection_helper<lua_engine::devenum<T>, T> { @@ -275,6 +289,34 @@ public: } }; + +template <> +struct usertype_container<plugin_options_plugins> : lua_engine::immutable_sequence_helper<plugin_options_plugins, std::list<plugin_options::plugin> > +{ +private: + using plugin_list = std::list<plugin_options::plugin>; + +public: + static int get(lua_State *L) + { + plugin_options_plugins &self(get_self(L)); + char const *const name(stack::unqualified_get<char const *>(L)); + auto const found(std::find_if( + self.options.plugins().begin(), + self.options.plugins().end(), + [&name] (plugin_options::plugin const &p) { return p.m_name == name; })); + if (self.options.plugins().end() != found) + return stack::push_reference(L, *found); + else + return stack::push(L, lua_nil); + } + + static int index_get(lua_State *L) + { + return get(L); + } +}; + } // namespace sol @@ -421,7 +463,7 @@ sol::object lua_engine::call_plugin(const std::string &name, sol::object in) else return res.get<sol::object>(); } - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; } void lua_engine::menu_populate(const std::string &menu, std::vector<std::tuple<std::string, std::string, std::string>> &menu_list) @@ -734,15 +776,15 @@ void lua_engine::initialize() emu["print_info"] = [] (const char *str) { osd_printf_info("%s\n", str); }; emu["print_debug"] = [] (const char *str) { osd_printf_debug("%s\n", str); }; emu["driver_find"] = - [this] (const char *driver) -> sol::object + [] (sol::this_state s, const char *driver) -> sol::object { const int i = driver_list::find(driver); if (i < 0) - return sol::make_object(sol(), sol::lua_nil); - return sol::make_object(sol(), driver_list::driver(i)); + return sol::lua_nil; + return sol::make_object(s, driver_list::driver(i)); }; emu["wait"] = lua_CFunction( - [](lua_State *L) + [] (lua_State *L) { lua_engine *engine = mame_machine_manager::instance()->lua(); luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected"); @@ -844,26 +886,26 @@ void lua_engine::initialize() file_type.set("open_next", &emu_file::open_next); file_type.set("seek", sol::overload( [](emu_file &file) { return file.tell(); }, - [this](emu_file &file, s64 offset, int whence) -> sol::object { + [this] (emu_file &file, s64 offset, int whence) -> sol::object { if(file.seek(offset, whence)) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; else return sol::make_object(sol(), file.tell()); }, [this](emu_file &file, const char* whence) -> sol::object { int wval = s_seek_parser(whence); if(wval < 0 || wval >= 3) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; if(file.seek(0, wval)) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; return sol::make_object(sol(), file.tell()); }, [this](emu_file &file, const char* whence, s64 offset) -> sol::object { int wval = s_seek_parser(whence); if(wval < 0 || wval >= 3) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; if(file.seek(offset, wval)) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; return sol::make_object(sol(), file.tell()); })); file_type.set("size", &emu_file::size); @@ -971,7 +1013,7 @@ void lua_engine::initialize() item_type.set("count", sol::readonly(&save_item::count)); item_type.set("read", [this](save_item &item, int offset) -> sol::object { if(!item.base || (offset >= item.count)) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; const void *const data = reinterpret_cast<const uint8_t *>(item.base) + (item.stride * (offset / item.valcount)); uint64_t ret = 0; switch(item.size) @@ -1157,7 +1199,7 @@ void lua_engine::initialize() }, [this](core_options::entry &e) -> sol::object { if (e.type() == core_options::option_type::INVALID) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; switch(e.type()) { case core_options::option_type::BOOLEAN: @@ -1177,53 +1219,17 @@ void lua_engine::initialize() core_options_entry_type.set("has_range", &core_options::entry::has_range); -/* running_machine library - * - * manager:machine() - * - * machine:exit() - close program - * machine:hard_reset() - hard reset emulation - * machine:soft_reset() - soft reset emulation - * machine:save(filename) - save state to filename - * machine:load(filename) - load state from filename - * machine:buffer_save() - return save state buffer as binary string - * machine:buffer_load(str) - load state from binary string buffer. returns true on success, otherwise nil - * machine:popmessage(str) - print str as popup - * machine:popmessage() - clear displayed popup message - * machine:logerror(str) - print str to log - * - * machine:system() - get game_driver for running driver - * machine:video() - get video_manager - * machine:sound() - get sound_manager - * machine:render() - get render_manager - * machine:ioport() - get ioport_manager - * machine:parameters() - get parameter_manager - * machine:memory() - get memory_manager - * machine:options() - get machine emu_options - * machine:outputs() - get output_manager - * machine:input() - get input_manager - * machine:uiinput() - get ui_input_manager - * machine:debugger() - get debugger_manager - * - * machine.paused - get paused state - * machine.samplerate - get audio sample rate - * machine.exit_pending - * machine.hard_reset_pending - * - * machine.devices[] - get device table (k=tag, v=device_t) - * machine.screens[] - get screens table (k=tag, v=screen_device) - * machine.images[] - get available image devices table (k=type, v=device_image_interface) - */ - auto machine_type = sol().registry().new_usertype<running_machine>("machine", sol::no_constructor); machine_type["exit"] = &running_machine::schedule_exit; machine_type["hard_reset"] = &running_machine::schedule_hard_reset; machine_type["soft_reset"] = &running_machine::schedule_soft_reset; - machine_type["save"] = &running_machine::schedule_save; - machine_type["load"] = &running_machine::schedule_load; + machine_type["save"] = &running_machine::schedule_save; // TODO: some kind of completion notification? + machine_type["load"] = &running_machine::schedule_load; // TODO: some kind of completion notification? machine_type["buffer_save"] = [] (running_machine &m, sol::this_state s) { + // FIXME: this needs to schedule saving to a buffer and return asynchronously somehow + // right now it's broken by anonymous timers, synchronize, etc. lua_State *L = s; luaL_Buffer buff; int size = ram_state::get_size(m.save()); @@ -1240,37 +1246,47 @@ void lua_engine::initialize() machine_type["buffer_load"] = [] (running_machine &m, sol::this_state s, std::string str) { - lua_State *L = s; + // FIXME: this needs to schedule loading from the buffer and return asynchronously somehow + // right now it's broken by anonymous timers, synchronize, etc. save_error error = m.save().read_buffer((u8 *)str.data(), str.size()); if (error == STATERR_NONE) + { return true; + } else { - luaL_error(L,"State load error."); + luaL_error(s,"State load error."); return false; } }; - machine_type["popmessage"] = sol::overload( - [](running_machine &m, const char *str) { m.popmessage("%s", str); }, - [](running_machine &m) { m.popmessage(); }); - machine_type["system"] = &running_machine::system; - machine_type["video"] = &running_machine::video; - machine_type["sound"] = &running_machine::sound; - machine_type["render"] = &running_machine::render; - machine_type["ioport"] = &running_machine::ioport; - machine_type["parameters"] = &running_machine::parameters; - machine_type["memory"] = &running_machine::memory; - machine_type["options"] = &running_machine::options; - machine_type["outputs"] = &running_machine::output; - machine_type["input"] = &running_machine::input; - machine_type["uiinput"] = &running_machine::ui_input; - machine_type["debugger"] = - [this] (running_machine &m) -> sol::object + machine_type["popmessage"] = + [] (running_machine &m, const char *str) { - if (!(m.debug_flags & DEBUG_FLAG_ENABLED)) - return sol::make_object(sol(), sol::lua_nil); - return sol::make_object(sol(), &m.debugger()); + if (str) + m.popmessage("%s", str); + else + m.popmessage(); }; + machine_type["logerror"] = [] (running_machine &m, std::string const *str) { m.logerror("[luaengine] %s\n", str); }; + machine_type["system"] = sol::property(&running_machine::system); + machine_type["video"] = sol::property(&running_machine::video); + machine_type["sound"] = sol::property(&running_machine::sound); + machine_type["render"] = sol::property(&running_machine::render); + machine_type["ioport"] = sol::property(&running_machine::ioport); + machine_type["parameters"] = sol::property(&running_machine::parameters); + machine_type["memory"] = sol::property(&running_machine::memory); + machine_type["options"] = sol::property(&running_machine::options); + machine_type["output"] = sol::property(&running_machine::output); + machine_type["input"] = sol::property(&running_machine::input); + machine_type["uiinput"] = sol::property(&running_machine::ui_input); + machine_type["debugger"] = sol::property( + [] (running_machine &m, sol::this_state s) -> sol::object + { + if (m.debug_flags & DEBUG_FLAG_ENABLED) + return sol::make_object(s, &m.debugger()); + else + return sol::lua_nil; + }); machine_type["paused"] = sol::property(&running_machine::paused); machine_type["samplerate"] = sol::property(&running_machine::sample_rate); machine_type["exit_pending"] = sol::property(&running_machine::exit_pending); @@ -1280,47 +1296,21 @@ void lua_engine::initialize() machine_type["cassettes"] = sol::property([] (running_machine &m) { return devenum<cassette_device_enumerator>(m.root_device()); }); machine_type["images"] = sol::property([] (running_machine &m) { return devenum<image_interface_enumerator>(m.root_device()); }); machine_type["slots"] = sol::property([](running_machine &m) { return devenum<slot_interface_enumerator>(m.root_device()); }); - machine_type["logerror"] = [] (running_machine &m, const char *str) { m.logerror("[luaengine] %s\n", str); }; - -/* game_driver library - * - * emu.driver_find(driver_name) - * - * driver.source_file - relative path to the source file - * driver.parent - * driver.name - * driver.description - * driver.year - * driver.manufacturer - * driver.compatible_with - * driver.default_layout - * driver.orientation - screen rotation degree (rot0/90/180/270) - * driver.type - machine type (arcade/console/computer/other) - * driver.not_working - not considered working - * driver.supports_save - supports save states - * driver.no_cocktail - screen flip support is missing - * driver.is_bios_root - this driver entry is a BIOS root - * driver.requires_artwork - requires external artwork for key game elements - * driver.clickable_artwork - artwork is clickable and requires mouse cursor - * driver.unofficial - unofficial hardware modification - * driver.no_sound_hw - system has no sound output - * driver.mechanical - contains mechanical parts (pinball, redemption games, ...) - * driver.is_incomplete - official system with blatantly incomplete hardware/software - */ auto game_driver_type = sol().registry().new_usertype<game_driver>("game_driver", sol::no_constructor); - game_driver_type["source_file"] = sol::property([] (game_driver const &driver) { return &driver.type.source()[0]; }); - game_driver_type["parent"] = sol::readonly(&game_driver::parent); game_driver_type["name"] = sol::property([] (game_driver const &driver) { return &driver.name[0]; }); game_driver_type["description"] = sol::property([] (game_driver const &driver) { return &driver.type.fullname()[0]; }); game_driver_type["year"] = sol::readonly(&game_driver::year); game_driver_type["manufacturer"] = sol::readonly(&game_driver::manufacturer); - game_driver_type["compatible_with"] = sol::readonly(&game_driver::compatible_with); - game_driver_type["default_layout"] = sol::readonly(&game_driver::default_layout); + game_driver_type["parent"] = sol::readonly(&game_driver::parent); + game_driver_type["compatible_with"] = sol::property([] (game_driver const &driver) { return strcmp(driver.compatible_with, "0") ? driver.compatible_with : nullptr; }); + game_driver_type["source_file"] = sol::property([] (game_driver const &driver) { return &driver.type.source()[0]; }); game_driver_type["orientation"] = sol::property( [] (game_driver const &driver) { + // FIXME: this works differently to the screen orientation function and the render target orientation property + // it should probably be made consistent with one of them std::string rot; switch (driver.flags & machine_flags::MASK_ORIENTATION) { @@ -1343,8 +1333,10 @@ void lua_engine::initialize() return rot; }); game_driver_type["type"] = sol::property( - [](game_driver const &driver) + [] (game_driver const &driver) { + // FIXME: this shouldn't be called type - there's potendial for confusion with the device type + // also, this should eventually go away in favour of richer flags std::string type; switch (driver.flags & machine_flags::MASK_TYPE) { @@ -1384,6 +1376,7 @@ void lua_engine::initialize() device_type["ioport"] = &device_t::ioport; device_type["subdevice"] = static_cast<device_t *(device_t::*)(char const *) const>(&device_t::subdevice); device_type["siblingdevice"] = static_cast<device_t *(device_t::*)(char const *) const>(&device_t::siblingdevice); + device_type["parameter"] = &device_t::parameter; device_type["tag"] = sol::property(&device_t::tag); device_type["basetag"] = sol::property(&device_t::basetag); device_type["name"] = sol::property(&device_t::name); @@ -1392,11 +1385,11 @@ void lua_engine::initialize() device_type["configured"] = sol::property(&device_t::configured); device_type["started"] = sol::property(&device_t::started); device_type["debug"] = sol::property( - [this] (device_t &dev) -> sol::object + [] (device_t &dev, sol::this_state s) -> sol::object { - if (!(dev.machine().debug_flags & DEBUG_FLAG_ENABLED) || !dynamic_cast<cpu_device *>(&dev)) // debugger not enabled or not cpu - return sol::make_object(sol(), sol::lua_nil); - return sol::make_object(sol(), dev.debug()); + if (!(dev.machine().debug_flags & DEBUG_FLAG_ENABLED) || !dynamic_cast<cpu_device *>(&dev)) // debugger not enabled or not CPU + return sol::lua_nil; + return sol::make_object(s, dev.debug()); }); device_type["spaces"] = sol::property( [this] (device_t &dev) @@ -1513,6 +1506,8 @@ void lua_engine::initialize() screen_dev_type["snapshot"] = [this] (screen_device &sdev, char const *filename) -> sol::object { + // FIXME: this shouldn't be a member of the screen device + // the screen is only used as a hint when configured for native snapshots and may be ignored std::string snapstr; bool is_absolute_path = false; if (filename) @@ -1534,20 +1529,20 @@ void lua_engine::initialize() // and save the snapshot machine().video().save_snapshot(&sdev, file); - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; }; screen_dev_type["pixel"] = [] (screen_device &sdev, s32 x, s32 y) { return sdev.pixel(x, y); }; screen_dev_type["pixels"] = [] (screen_device &sdev, sol::this_state s) { - lua_State *L = s; + // TODO: would be better if this could return a tuple of (buffer, width, height) const rectangle &visarea = sdev.visible_area(); luaL_Buffer buff; int size = visarea.height() * visarea.width() * 4; - u32 *ptr = (u32 *)luaL_buffinitsize(L, &buff, size); + u32 *ptr = (u32 *)luaL_buffinitsize(s, &buff, size); sdev.pixels(ptr); luaL_pushresultsize(&buff, size); - return sol::make_reference(L, sol::stack_reference(L, -1)); + return sol::make_reference(s, sol::stack_reference(s, -1)); }; screen_dev_type["screen_type"] = sol::property(&screen_device::screen_type); screen_dev_type["width"] = sol::property([] (screen_device &sdev) { return sdev.visible_area().width(); }); @@ -1664,147 +1659,103 @@ void lua_engine::initialize() dislot_option_type["clock"] = sol::property(static_cast<u32 (device_slot_interface::slot_option::*)() const>(&device_slot_interface::slot_option::clock)); -/* parameters_manager library - * - * manager:machine():parameters() - * - * parameters:add(tag, val) - add tag = val parameter - * parameters:lookup(tag) - get val for tag - */ - - auto parameters_type = sol().registry().new_usertype<parameters_manager>("parameters", "new", sol::no_constructor); + auto parameters_type = sol().registry().new_usertype<parameters_manager>("parameters", sol::no_constructor); parameters_type["add"] = ¶meters_manager::add; parameters_type["lookup"] = ¶meters_manager::lookup; -/* video_manager library - * - * manager:machine():video() - * - * video:begin_recording([opt] filename, [opt] format) - start AVI recording to filename if given or default - * video:end_recording() - stop AVI recording - * video:is_recording() - get recording status - * video:snapshot() - save shot of all screens - * video:skip_this_frame() - is current frame going to be skipped - * video:speed_factor() - get speed factor - * video:speed_percent() - get percent from realtime - * video:frame_update() - render a frame - * video:size() - get width and height of snapshot bitmap in pixels - * video:pixels() - get binary bitmap of all screens as string - * - * video.frameskip - current frameskip - * video.throttled - throttle state - * video.throttle_rate - throttle rate - */ - - auto video_type = sol().registry().new_usertype<video_manager>("video", "new", sol::no_constructor); - video_type.set("begin_recording", sol::overload( - [this](video_manager &vm, const char *filename, const char *format_string) { - std::string fn = process_snapshot_filename(machine(), filename); - movie_recording::format format = s_movie_recording_format_parser(format_string); - vm.begin_recording(fn.c_str(), format); - }, - [this](video_manager &vm, const char *filename) { - std::string fn = process_snapshot_filename(machine(), filename); - vm.begin_recording(fn.c_str(), movie_recording::format::AVI); - }, - [](video_manager &vm) { - vm.begin_recording(nullptr, movie_recording::format::AVI); - })); - video_type.set("end_recording", [this](video_manager &vm) { - if(!vm.is_recording()) - { - machine().logerror("[luaengine] No active recording to stop\n"); - return; - } - vm.end_recording(); - }); - video_type.set("snapshot", &video_manager::save_active_screen_snapshots); - video_type.set("is_recording", &video_manager::is_recording); - video_type.set("skip_this_frame", &video_manager::skip_this_frame); - video_type.set("speed_factor", &video_manager::speed_factor); - video_type.set("speed_percent", &video_manager::speed_percent); - video_type.set("effective_frameskip", &video_manager::effective_frameskip); - video_type.set("frame_update", &video_manager::frame_update); - video_type.set("size", [](video_manager &vm) { + auto video_type = sol().registry().new_usertype<video_manager>("video", sol::no_constructor); + video_type["frame_update"] = [] (video_manager &vm) { vm.frame_update(true); }; + video_type["snapshot"] = &video_manager::save_active_screen_snapshots; + video_type["begin_recording"] = + [this] (video_manager &vm, const char *filename, const char *format_string) + { + // FIXME: the filename substitution shouldn't be done here + std::string fn; + movie_recording::format format = movie_recording::format::AVI; + if (filename) + fn = process_snapshot_filename(machine(), filename); + if (format_string) + format = s_movie_recording_format_parser(format_string); + vm.begin_recording(filename ? fn.c_str() : nullptr, format); + }; + video_type["end_recording"] = &video_manager::end_recording; + video_type["snapshot_size"] = + [] (video_manager &vm) + { s32 width, height; vm.compute_snapshot_size(width, height); - return std::tuple<s32, s32>(width, height); - }); - video_type.set("pixels", [](video_manager &vm, sol::this_state s) { - lua_State *L = s; - luaL_Buffer buff; + return std::make_tuple(width, height); + }; + video_type["snapshot_pixels"] = + [] (video_manager &vm, sol::this_state s) + { + // TODO: would be better if this could return a tuple of (buffer, width, height) s32 width, height; vm.compute_snapshot_size(width, height); int size = width * height * 4; - u32 *ptr = (u32 *)luaL_buffinitsize(L, &buff, size); + luaL_Buffer buff; + u32 *ptr = (u32 *)luaL_buffinitsize(s, &buff, size); vm.pixels(ptr); luaL_pushresultsize(&buff, size); - return sol::make_reference(L, sol::stack_reference(L, -1)); - }); - video_type.set("frameskip", sol::property(&video_manager::frameskip, &video_manager::set_frameskip)); - video_type.set("throttled", sol::property(&video_manager::throttled, &video_manager::set_throttled)); - video_type.set("throttle_rate", sol::property(&video_manager::throttle_rate, &video_manager::set_throttle_rate)); - - -/* sound_manager library - * - * manager:machine():sound() - * - * sound:start_recording() - begin audio recording - * sound:stop_recording() - end audio recording - * sound:ui_mute(turn_off) - turns on/off UI sound - * sound:system_mute() - turns on/off system sound - * sound:samples() - get current audio buffer contents in binary form as string (updates 50 times per second) - * - * sound.attenuation - sound attenuation - */ - - auto sound_type = sol().registry().new_usertype<sound_manager>("sound", "new", sol::no_constructor); - sound_type.set("start_recording", &sound_manager::start_recording); - sound_type.set("stop_recording", &sound_manager::stop_recording); - sound_type.set("ui_mute", &sound_manager::ui_mute); - sound_type.set("debugger_mute", &sound_manager::debugger_mute); - sound_type.set("system_mute", &sound_manager::system_mute); - sound_type.set("samples", [](sound_manager &sm, sol::this_state s) { - lua_State *L = s; + return sol::make_reference(s, sol::stack_reference(s, -1)); + }; + video_type["speed_factor"] = sol::property(&video_manager::speed_factor); + video_type["throttled"] = sol::property(&video_manager::throttled, &video_manager::set_throttled); + video_type["throttle_rate"] = sol::property(&video_manager::throttle_rate, &video_manager::set_throttle_rate); + video_type["frameskip"] = sol::property(&video_manager::frameskip, &video_manager::set_frameskip); + video_type["speed_percent"] = sol::property(&video_manager::speed_percent); + video_type["effective_frameskip"] = sol::property(&video_manager::effective_frameskip); + video_type["skip_this_frame"] = sol::property(&video_manager::skip_this_frame); + video_type["snap_native"] = sol::property(&video_manager::snap_native); + video_type["is_recording"] = sol::property(&video_manager::is_recording); + video_type["snapshot_target"] = sol::property(&video_manager::snapshot_target); + + + auto sound_type = sol().registry().new_usertype<sound_manager>("sound", sol::no_constructor); + sound_type["start_recording"] = + [] (sound_manager &sm, char const *filename) + { + return filename ? sm.start_recording(filename) : sm.start_recording(); + }; + sound_type["stop_recording"] = &sound_manager::stop_recording; + sound_type["get_samples"] = + [] (sound_manager &sm, sol::this_state s) + { luaL_Buffer buff; - s32 count = sm.sample_count() * 2 * 2; // 2 channels, 2 bytes per sample - s16 *ptr = (s16 *)luaL_buffinitsize(L, &buff, count); + s32 const count = sm.sample_count() * 2 * 2; // 2 channels, 2 bytes per sample + s16 *const ptr = (s16 *)luaL_buffinitsize(s, &buff, count); sm.samples(ptr); luaL_pushresultsize(&buff, count); - return sol::make_reference(L, sol::stack_reference(L, -1)); - }); - sound_type.set("attenuation", sol::property(&sound_manager::attenuation, &sound_manager::set_attenuation)); - - -/* mame_ui_manager library - * - * manager:ui() - * - * ui:is_menu_active() - ui menu state - * ui:options() - ui core_options - * ui:get_line_height() - current ui font height - * ui:get_string_width(str, scale) - get str width with ui font at scale factor of current font size - * ui:get_char_width(char) - get width of utf8 glyph char with ui font - * ui:set_aggressive_input_focus(bool) - * - * ui.single_step - * ui.show_fps - fps display enabled - * ui.show_profiler - profiler display enabled - */ - - auto ui_type = sol().registry().new_usertype<mame_ui_manager>("ui", "new", sol::no_constructor); - ui_type.set("is_menu_active", &mame_ui_manager::is_menu_active); - ui_type.set("options", [](mame_ui_manager &m) { return static_cast<core_options *>(&m.options()); }); - ui_type.set("show_fps", sol::property(&mame_ui_manager::show_fps, &mame_ui_manager::set_show_fps)); - ui_type.set("show_profiler", sol::property(&mame_ui_manager::show_profiler, &mame_ui_manager::set_show_profiler)); - ui_type.set("single_step", sol::property(&mame_ui_manager::single_step, &mame_ui_manager::set_single_step)); - ui_type.set("get_line_height", &mame_ui_manager::get_line_height); - ui_type.set("get_string_width", &mame_ui_manager::get_string_width); + return sol::make_reference(s, sol::stack_reference(s, -1)); + }; + sound_type["muted"] = sol::property(&sound_manager::muted); + sound_type["ui_mute"] = sol::property( + static_cast<bool (sound_manager::*)() const>(&sound_manager::ui_mute), + static_cast<void (sound_manager::*)(bool)>(&sound_manager::ui_mute)); + sound_type["debugger_mute"] = sol::property( + static_cast<bool (sound_manager::*)() const>(&sound_manager::debugger_mute), + static_cast<void (sound_manager::*)(bool)>(&sound_manager::debugger_mute)); + sound_type["system_mute"] = sol::property( + static_cast<bool (sound_manager::*)() const>(&sound_manager::system_mute), + static_cast<void (sound_manager::*)(bool)>(&sound_manager::system_mute)); + sound_type["attenuation"] = sol::property( + &sound_manager::attenuation, + &sound_manager::set_attenuation); + sound_type["recording"] = sol::property(&sound_manager::is_recording); + + + auto ui_type = sol().registry().new_usertype<mame_ui_manager>("ui", sol::no_constructor); // sol converts char32_t to a string - ui_type.set("get_char_width", [](mame_ui_manager &m, uint32_t utf8char) { return m.get_char_width(utf8char); }); - ui_type.set("set_aggressive_input_focus", [](mame_ui_manager &m, bool aggressive_focus) { osd_set_aggressive_input_focus(aggressive_focus); }); + ui_type["get_char_width"] = [] (mame_ui_manager &m, uint32_t utf8char) { return m.get_char_width(utf8char); }; + ui_type["get_string_width"] = &mame_ui_manager::get_string_width; + ui_type["set_aggressive_input_focus"] = [](mame_ui_manager &m, bool aggressive_focus) { osd_set_aggressive_input_focus(aggressive_focus); }; + ui_type["options"] = sol::property([] (mame_ui_manager &m) { return static_cast<core_options *>(&m.options()); }); + ui_type["line_height"] = sol::property(&mame_ui_manager::get_line_height); + ui_type["menu_active"] = sol::property(&mame_ui_manager::is_menu_active); + ui_type["single_step"] = sol::property(&mame_ui_manager::single_step, &mame_ui_manager::set_single_step); + ui_type["show_fps"] = sol::property(&mame_ui_manager::show_fps, &mame_ui_manager::set_show_fps); + ui_type["show_profiler"] = sol::property(&mame_ui_manager::show_profiler, &mame_ui_manager::set_show_profiler); /* device_state_entry library @@ -1861,64 +1812,40 @@ void lua_engine::initialize() rom_entry_type.set("flags", &rom_entry::get_flags); -/* output_manager library - * - * manager:machine():outputs() - * - * outputs:set_value(name, val) - set output name to val - * outputs:set_indexed_value(index, val) - set output index to val - * outputs:get_value(name) - get output name value - * outputs:get_indexed_value(index) - get output index value - * outputs:name_to_id(name) - get index for name - * outputs:id_to_name(index) - get name for index - */ - - auto output_type = sol().registry().new_usertype<output_manager>("output", "new", sol::no_constructor); - output_type.set("set_value", &output_manager::set_value); - output_type.set("set_indexed_value", [](output_manager &o, char const *basename, int index, int value) { + auto output_type = sol().registry().new_usertype<output_manager>("output", sol::no_constructor); + output_type["set_value"] = &output_manager::set_value; + output_type["set_indexed_value"] = + [] (output_manager &o, char const *basename, int index, int value) + { o.set_value(util::string_format("%s%d", basename, index).c_str(), value); - }); - output_type.set("get_value", &output_manager::get_value); - output_type.set("get_indexed_value", [](output_manager &o, char const *basename, int index) { + }; + output_type["get_value"] = &output_manager::get_value; + output_type["get_indexed_value"] = + [] (output_manager &o, char const *basename, int index) + { return o.get_value(util::string_format("%s%d", basename, index).c_str()); - }); - output_type.set("name_to_id", &output_manager::name_to_id); - output_type.set("id_to_name", &output_manager::id_to_name); - + }; + output_type["name_to_id"] = &output_manager::name_to_id; + output_type["id_to_name"] = &output_manager::id_to_name; -/* mame_machine_manager library - * - * manager - * mame_manager - alias of manager - * - * manager:machine() - running machine - * manager:options() - emu options - * manager:plugins() - plugin options - * manager:ui() - mame ui manager - */ - sol().registry().new_usertype<mame_machine_manager>("manager", "new", sol::no_constructor, - "machine", &machine_manager::machine, - "options", &machine_manager::options, - "plugins", [this](mame_machine_manager &m) { - sol::table table = sol().create_table(); - for (auto &curentry : m.plugins().plugins()) - { - sol::table plugin_table = sol().create_table(); - plugin_table["name"] = curentry.m_name; - plugin_table["description"] = curentry.m_description; - plugin_table["type"] = curentry.m_type; - plugin_table["directory"] = curentry.m_directory; - plugin_table["start"] = curentry.m_start; - table[curentry.m_name] = plugin_table; - } - return table; - }, - "ui", &mame_machine_manager::ui); + auto mame_manager_type = sol().registry().new_usertype<mame_machine_manager>("manager", sol::no_constructor); + mame_manager_type["machine"] = sol::property(&mame_machine_manager::machine); + mame_manager_type["ui"] = sol::property(&mame_machine_manager::ui); + mame_manager_type["options"] = sol::property(&mame_machine_manager::options); + mame_manager_type["plugins"] = sol::property([] (mame_machine_manager &m) { return plugin_options_plugins(m.plugins()); }); sol()["manager"] = std::ref(*mame_machine_manager::instance()); sol()["mame_manager"] = std::ref(*mame_machine_manager::instance()); + auto plugin_type = sol().registry().new_usertype<plugin_options::plugin>("plugin", sol::no_constructor); + plugin_type["name"] = sol::readonly(&plugin_options::plugin::m_name); + plugin_type["description"] = sol::readonly(&plugin_options::plugin::m_description); + plugin_type["type"] = sol::readonly(&plugin_options::plugin::m_type); + plugin_type["directory"] = sol::readonly(&plugin_options::plugin::m_directory); + plugin_type["start"] = sol::readonly(&plugin_options::plugin::m_start); + + // set up other user types initialize_debug(emu); initialize_input(emu); diff --git a/src/frontend/mame/luaengine_debug.cpp b/src/frontend/mame/luaengine_debug.cpp index 7297a7f82a3..e3817d95ced 100644 --- a/src/frontend/mame/luaengine_debug.cpp +++ b/src/frontend/mame/luaengine_debug.cpp @@ -29,24 +29,25 @@ struct wrap_textbuf }; -sol::object do_breakpoint_enable(lua_State *L, device_debug &dev, sol::object &index, bool enable) +template <bool Enable> +sol::object do_breakpoint_enable(device_debug &dev, sol::this_state s, sol::object index) { if (index == sol::lua_nil) { - dev.breakpoint_enable_all(enable); + dev.breakpoint_enable_all(Enable); 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>()) { - bool result(dev.breakpoint_enable(index.as<int>(), enable)); + bool result(dev.breakpoint_enable(index.as<int>(), Enable)); 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(L, result); + return sol::make_object(s, result); } else { @@ -56,20 +57,21 @@ sol::object do_breakpoint_enable(lua_State *L, device_debug &dev, sol::object &i } -sol::object do_watchpoint_enable(lua_State *L, device_debug &dev, sol::object &index, bool enable) +template <bool Enable> +sol::object do_watchpoint_enable(device_debug &dev, sol::this_state s, sol::object index) { if (index == sol::lua_nil) { - dev.watchpoint_enable_all(enable); + dev.watchpoint_enable_all(Enable); dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS); return sol::lua_nil; } else if (index.is<int>()) { - bool result(dev.watchpoint_enable(index.as<int>(), enable)); + bool result(dev.watchpoint_enable(index.as<int>(), Enable)); if (result) dev.device().machine().debug_view().update_all(DVT_WATCH_POINTS); - return sol::make_object(L, result); + return sol::make_object(s, result); } else { @@ -162,8 +164,8 @@ void lua_engine::initialize_debug(sol::table &emu) 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["bpenable"] = &do_breakpoint_enable<true>; + device_debug_type["bpdisable"] = &do_breakpoint_enable<false>; device_debug_type["bplist"] = [this] (device_debug &dev) { @@ -193,8 +195,8 @@ void lua_engine::initialize_debug(sol::table &emu) 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["wpenable"] = &do_watchpoint_enable<true>; + device_debug_type["wpdisable"] = &do_watchpoint_enable<false>; device_debug_type["wplist"] = [this] (device_debug &dev, addr_space &sp) { diff --git a/src/frontend/mame/luaengine_render.cpp b/src/frontend/mame/luaengine_render.cpp index b910a717561..8a84fcc4e82 100644 --- a/src/frontend/mame/luaengine_render.cpp +++ b/src/frontend/mame/luaengine_render.cpp @@ -348,12 +348,12 @@ void lua_engine::initialize_render(sol::table &emu) } }; layout_view_item_type["id"] = sol::property( - [this] (layout_view::item &i) -> sol::object + [] (layout_view::item &i, sol::this_state s) -> sol::object { if (i.id().empty()) - return sol::make_object(sol(), sol::lua_nil); + return sol::lua_nil; else - return sol::make_object(sol(), i.id()); + return sol::make_object(s, i.id()); }); layout_view_item_type["bounds_animated"] = sol::property(&layout_view::item::bounds_animated); layout_view_item_type["color_animated"] = sol::property(&layout_view::item::color_animated); diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp index a461a08b7e6..f48cbd46563 100644 --- a/src/frontend/mame/mame.cpp +++ b/src/frontend/mame/mame.cpp @@ -166,7 +166,7 @@ void mame_machine_manager::start_luaengine() // process includes for (const std::string &incl : split(options().plugin(), ',')) { - plugin *p = m_plugins->find(incl); + plugin_options::plugin *p = m_plugins->find(incl); if (!p) fatalerror("Fatal error: Could not load plugin: %s\n", incl); p->m_start = true; @@ -175,7 +175,7 @@ void mame_machine_manager::start_luaengine() // process excludes for (const std::string &excl : split(options().no_plugin(), ',')) { - plugin *p = m_plugins->find(excl); + plugin_options::plugin *p = m_plugins->find(excl); if (!p) fatalerror("Fatal error: Unknown plugin: %s\n", excl); p->m_start = false; @@ -185,7 +185,7 @@ void mame_machine_manager::start_luaengine() // we have a special way to open the console plugin if (options().console()) { - plugin *p = m_plugins->find(OPTION_CONSOLE); + plugin_options::plugin *p = m_plugins->find(OPTION_CONSOLE); if (!p) fatalerror("Fatal error: Console plugin not found.\n"); diff --git a/src/frontend/mame/pluginopts.cpp b/src/frontend/mame/pluginopts.cpp index 3828be3c8cd..2dda2062064 100644 --- a/src/frontend/mame/pluginopts.cpp +++ b/src/frontend/mame/pluginopts.cpp @@ -107,7 +107,7 @@ bool plugin_options::load_plugin(const std::string &path) // find //------------------------------------------------- -plugin *plugin_options::find(const std::string &name) +plugin_options::plugin *plugin_options::find(const std::string &name) { auto iter = std::find_if( m_plugins.begin(), @@ -139,7 +139,7 @@ static core_options create_core_options(const plugin_options &plugin_opts) opts.add_entries(s_option_entries); // create an entry for each option - for (const plugin &p : plugin_opts.plugins()) + for (const plugin_options::plugin &p : plugin_opts.plugins()) { opts.add_entry( { p.m_name }, diff --git a/src/frontend/mame/pluginopts.h b/src/frontend/mame/pluginopts.h index 3565f5d9e78..41c688b2ab6 100644 --- a/src/frontend/mame/pluginopts.h +++ b/src/frontend/mame/pluginopts.h @@ -17,23 +17,20 @@ #include <string> -// ======================> plugin - -struct plugin -{ - std::string m_name; - std::string m_description; - std::string m_type; - std::string m_directory; - bool m_start; -}; - - // ======================> plugin_options class plugin_options { public: + struct plugin + { + std::string m_name; + std::string m_description; + std::string m_type; + std::string m_directory; + bool m_start; + }; + plugin_options(); // accessors diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index dc5cc2ba9a3..b9b55264ca4 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -886,7 +886,7 @@ void menu_plugins_configure::handle() { if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT || menu_event->iptkey == IPT_UI_SELECT) { - plugin *p = plugins.find((const char*)menu_event->itemref); + plugin_options::plugin *p = plugins.find((const char*)menu_event->itemref); if (p) { p->m_start = !p->m_start; diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 1273c5e92df..7ba294c446c 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -1381,7 +1381,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container) // toggle throttle? if (machine().ui_input().pressed(IPT_UI_THROTTLE)) - machine().video().toggle_throttle(); + machine().video().set_throttled(!machine().video().throttled()); // check for fast forward if (machine().ioport().type_pressed(IPT_UI_FAST_FORWARD)) diff --git a/src/lib/util/bitmap.cpp b/src/lib/util/bitmap.cpp index fc05b89f1b6..cfad01ac82f 100644 --- a/src/lib/util/bitmap.cpp +++ b/src/lib/util/bitmap.cpp @@ -280,23 +280,25 @@ void bitmap_t::resize(int width, int height, int xslop, int yslop) int new_rowpixels = compute_rowpixels(width, xslop); uint32_t new_allocbytes = new_rowpixels * (height + 2 * yslop) * m_bpp / 8; - // if we need more memory, just realloc if (new_allocbytes > m_allocbytes) { - palette_t *palette = m_palette; + // if we need more memory, just realloc + palette_t *const palette = m_palette; allocate(width, height, xslop, yslop); set_palette(palette); - return; } + else + { - // otherwise, reconfigure - m_rowpixels = new_rowpixels; - m_width = width; - m_height = height; - m_cliprect.set(0, width - 1, 0, height - 1); + // otherwise, reconfigure + m_rowpixels = new_rowpixels; + m_width = width; + m_height = height; + m_cliprect.set(0, width - 1, 0, height - 1); - // re-compute the base - compute_base(xslop, yslop); + // re-compute the base + compute_base(xslop, yslop); + } } /** diff --git a/src/lib/util/wavwrite.cpp b/src/lib/util/wavwrite.cpp index 56a7cd4e43b..7ebbdf5240d 100644 --- a/src/lib/util/wavwrite.cpp +++ b/src/lib/util/wavwrite.cpp @@ -6,34 +6,34 @@ #include <cstdio> #include <new> -#include <memory> +#include <vector> +namespace util { + struct wav_file { FILE *file = nullptr; + std::vector<std::int16_t> temp; std::uint32_t total_offs = 0U; std::uint32_t data_offs = 0U; }; -wav_file *wav_open(const char *filename, int sample_rate, int channels) +wav_file_ptr wav_open(std::string_view filename, int sample_rate, int channels) { std::uint32_t temp32; std::uint16_t temp16; // allocate memory for the wav struct - auto *const wav = new (std::nothrow) wav_file; + wav_file_ptr wav(new (std::nothrow) wav_file); if (!wav) return nullptr; - // create the file */ - wav->file = std::fopen(filename, "wb"); + // create the file + wav->file = std::fopen(std::string(filename).c_str(), "wb"); // ugly - need to force NUL termination on filename if (!wav->file) - { - delete wav; return nullptr; - } // write the 'RIFF' header std::fwrite("RIFF", 1, 4, wav->file); @@ -96,93 +96,99 @@ void wav_close(wav_file *wav) if (!wav) return; - std::uint32_t temp32; - std::uint32_t const total = std::ftell(wav->file); - - // update the total file size - std::fseek(wav->file, wav->total_offs, SEEK_SET); - temp32 = total - (wav->total_offs + 4); - temp32 = little_endianize_int32(temp32); - std::fwrite(&temp32, 1, 4, wav->file); - - // update the data size - std::fseek(wav->file, wav->data_offs, SEEK_SET); - temp32 = total - (wav->data_offs + 4); - temp32 = little_endianize_int32(temp32); - std::fwrite(&temp32, 1, 4, wav->file); + if (wav->file) + { + std::uint32_t temp32; + std::uint32_t const total = std::ftell(wav->file); + + // update the total file size + std::fseek(wav->file, wav->total_offs, SEEK_SET); + temp32 = total - (wav->total_offs + 4); + temp32 = little_endianize_int32(temp32); + std::fwrite(&temp32, 1, 4, wav->file); + + // update the data size + std::fseek(wav->file, wav->data_offs, SEEK_SET); + temp32 = total - (wav->data_offs + 4); + temp32 = little_endianize_int32(temp32); + std::fwrite(&temp32, 1, 4, wav->file); + + std::fclose(wav->file); + } - std::fclose(wav->file); delete wav; } -void wav_add_data_16(wav_file *wav, int16_t *data, int samples) +void wav_add_data_16(wav_file &wav, int16_t *data, int samples) { - if (!wav) - return; - // just write and flush the data - std::fwrite(data, 2, samples, wav->file); - std::fflush(wav->file); + std::fwrite(data, 2, samples, wav.file); + std::fflush(wav.file); } -void wav_add_data_32(wav_file *wav, int32_t *data, int samples, int shift) +void wav_add_data_32(wav_file &wav, int32_t *data, int samples, int shift) { - if (!wav || !samples) + if (!samples) return; - // resize dynamic array - std::unique_ptr<int16_t []> temp(new int16_t [samples]); + // resize dynamic array - don't want it to copy if it needs to expand + wav.temp.clear(); + wav.temp.resize(samples); // clamp for (int i = 0; i < samples; i++) { int val = data[i] >> shift; - temp[i] = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; + wav.temp[i] = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; } // write and flush - std::fwrite(&temp[0], 2, samples, wav->file); - std::fflush(wav->file); + std::fwrite(&wav.temp[0], 2, samples, wav.file); + std::fflush(wav.file); } -void wav_add_data_16lr(wav_file *wav, int16_t *left, int16_t *right, int samples) +void wav_add_data_16lr(wav_file &wav, int16_t *left, int16_t *right, int samples) { - if (!wav || !samples) + if (!samples) return; - // resize dynamic array - std::unique_ptr<int16_t []> temp(new int16_t [samples * 2]); + // resize dynamic array - don't want it to copy if it needs to expand + wav.temp.clear(); + wav.temp.resize(samples * 2); // interleave for (int i = 0; i < samples * 2; i++) - temp[i] = (i & 1) ? right[i / 2] : left[i / 2]; + wav.temp[i] = (i & 1) ? right[i / 2] : left[i / 2]; // write and flush - std::fwrite(&temp[0], 4, samples, wav->file); - std::fflush(wav->file); + std::fwrite(&wav.temp[0], 4, samples, wav.file); + std::fflush(wav.file); } -void wav_add_data_32lr(wav_file *wav, int32_t *left, int32_t *right, int samples, int shift) +void wav_add_data_32lr(wav_file &wav, int32_t *left, int32_t *right, int samples, int shift) { - if (!wav || !samples) + if (!samples) return; - // resize dynamic array - std::unique_ptr<int16_t []> temp(new int16_t [samples * 2]); + // resize dynamic array - don't want it to copy if it needs to expand + wav.temp.clear(); + wav.temp.resize(samples * 2); // interleave for (int i = 0; i < samples * 2; i++) { int val = (i & 1) ? right[i / 2] : left[i / 2]; val >>= shift; - temp[i] = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; + wav.temp[i] = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; } // write and flush - std::fwrite(&temp[0], 4, samples, wav->file); - std::fflush(wav->file); + std::fwrite(&wav.temp[0], 4, samples, wav.file); + std::fflush(wav.file); } + +} // namespace util diff --git a/src/lib/util/wavwrite.h b/src/lib/util/wavwrite.h index cdf6f4d0d78..3f6ac6fd5c1 100644 --- a/src/lib/util/wavwrite.h +++ b/src/lib/util/wavwrite.h @@ -6,16 +6,34 @@ #pragma once #include <cstdint> +#include <memory> +#include <string_view> +namespace util { + struct wav_file; -wav_file *wav_open(const char *filename, int sample_rate, int channels); void wav_close(wav_file *wavptr); -void wav_add_data_16(wav_file *wavptr, std::int16_t *data, int samples); -void wav_add_data_32(wav_file *wavptr, std::int32_t *data, int samples, int shift); -void wav_add_data_16lr(wav_file *wavptr, std::int16_t *left, std::int16_t *right, int samples); -void wav_add_data_32lr(wav_file *wavptr, std::int32_t *left, std::int32_t *right, int samples, int shift); +struct wav_deleter +{ + void operator()(wav_file *wavptr) const + { + if (wavptr) + wav_close(wavptr); + } +}; + +using wav_file_ptr = std::unique_ptr<wav_file, wav_deleter>; + +wav_file_ptr wav_open(std::string_view filename, int sample_rate, int channels); + +void wav_add_data_16(wav_file &wavptr, std::int16_t *data, int samples); +void wav_add_data_32(wav_file &wavptr, std::int32_t *data, int samples, int shift); +void wav_add_data_16lr(wav_file &wavptr, std::int16_t *left, std::int16_t *right, int samples); +void wav_add_data_32lr(wav_file &wavptr, std::int32_t *left, std::int32_t *right, int samples, int shift); + +} // namespace util #endif // MAME_UTIL_WAVWRITE_H diff --git a/src/mame/audio/8080bw.cpp b/src/mame/audio/8080bw.cpp index 2ae312b7d13..0c29da35891 100644 --- a/src/mame/audio/8080bw.cpp +++ b/src/mame/audio/8080bw.cpp @@ -109,16 +109,16 @@ void _8080bw_state::invadpt2_sh_port_1_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - m_sn->enable_w(!(data & 0x01)); /* SAUCER SOUND */ + m_sn->enable_w(!BIT(data, 0)); // SAUCER SOUND - if (rising_bits & 0x02) m_samples->start(0, 0); /* MISSLE SOUND */ - if (rising_bits & 0x04) m_samples->start(1, 1); /* EXPLOSION */ - if (rising_bits & 0x08) m_samples->start(2, 2); /* INVADER HIT */ - if (rising_bits & 0x10) m_samples->start(5, 8); /* BONUS MISSILE BASE */ + if (BIT(rising_bits, 1)) m_samples->start(0, 0); // MISSLE SOUND + if (BIT(rising_bits, 2)) m_samples->start(1, 1); // EXPLOSION + if (BIT(rising_bits, 3)) m_samples->start(2, 2); // INVADER HIT + if (BIT(rising_bits, 4)) m_samples->start(5, 8); // BONUS MISSILE BASE m_screen_red = data & 0x04; - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_port_1_last_extra = data; } @@ -134,11 +134,11 @@ void _8080bw_state::invadpt2_sh_port_2_w(uint8_t data) uint8_t rising_bits = data & ~m_port_2_last_extra; - if (rising_bits & 0x01) m_samples->start(4, 3); /* FLEET */ - if (rising_bits & 0x02) m_samples->start(4, 4); /* FLEET */ - if (rising_bits & 0x04) m_samples->start(4, 5); /* FLEET */ - if (rising_bits & 0x08) m_samples->start(4, 6); /* FLEET */ - if (rising_bits & 0x10) m_samples->start(3, 7); /* SAUCER HIT */ + if (BIT(rising_bits, 0)) m_samples->start(4, 3); // FLEET + if (BIT(rising_bits, 1)) m_samples->start(4, 4); // FLEET + if (BIT(rising_bits, 2)) m_samples->start(4, 5); // FLEET + if (BIT(rising_bits, 3)) m_samples->start(4, 6); // FLEET + if (BIT(rising_bits, 4)) m_samples->start(3, 7); // SAUCER HIT m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); m_color_map = BIT(data, 5); @@ -158,11 +158,11 @@ void _8080bw_state::spacerng_sh_port_2_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_2_last_extra; - if (rising_bits & 0x01) m_samples->start(4, 3); /* FLEET */ - if (rising_bits & 0x02) m_samples->start(4, 4); /* FLEET */ - if (rising_bits & 0x04) m_samples->start(4, 5); /* FLEET */ - if (rising_bits & 0x08) m_samples->start(4, 6); /* FLEET */ - if (rising_bits & 0x10) m_samples->start(3, 7); /* SAUCER HIT */ + if (BIT(rising_bits, 0)) m_samples->start(4, 3); // FLEET + if (BIT(rising_bits, 1)) m_samples->start(4, 4); // FLEET + if (BIT(rising_bits, 2)) m_samples->start(4, 5); // FLEET + if (BIT(rising_bits, 3)) m_samples->start(4, 6); // FLEET + if (BIT(rising_bits, 4)) m_samples->start(3, 7); // SAUCER HIT m_flip_screen = BIT(~data, 5) & ioport(CABINET_PORT_TAG)->read(); @@ -179,13 +179,13 @@ void _8080bw_state::spcewars_sh_port_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - m_sn->enable_w(!(data & 0x01)); /* Saucer Sound */ + m_sn->enable_w(!BIT(data, 0)); // Saucer Sound - if (rising_bits & 0x02) m_samples->start(0, 0); /* Shot Sound */ - if (rising_bits & 0x04) m_samples->start(1, 1); /* Base Hit */ - if (rising_bits & 0x08) m_samples->start(2, 2); /* Invader Hit */ + if (BIT(rising_bits, 1)) m_samples->start(0, 0); // Shot Sound + if (BIT(rising_bits, 2)) m_samples->start(1, 1); // Base Hit + if (BIT(rising_bits, 3)) m_samples->start(2, 2); // Invader Hit - m_speaker->level_w(BIT(data, 4)); /* Various bitstream tunes */ + m_speaker->level_w(BIT(data, 4)); // Various bitstream tunes m_port_1_last_extra = data; } @@ -217,13 +217,13 @@ void _8080bw_state::lrescue_sh_port_1_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - if (rising_bits & 0x01) m_samples->start(0, 3); /* Thrust */ - if (rising_bits & 0x02) m_samples->start(1, 2); /* Shot Sound */ - if (rising_bits & 0x04) m_samples->start(0, 1); /* Death */ - if (rising_bits & 0x08) m_samples->start(1, 0); /* Alien Hit */ - if (rising_bits & 0x10) m_samples->start(2, 5); /* Bonus Ship (not confirmed) */ + if (BIT(rising_bits, 0)) m_samples->start(0, 3); // Thrust + if (BIT(rising_bits, 1)) m_samples->start(1, 2); // Shot Sound + if (BIT(rising_bits, 2)) m_samples->start(0, 1); // Death + if (BIT(rising_bits, 3)) m_samples->start(1, 0); // Alien Hit + if (BIT(rising_bits, 4)) m_samples->start(2, 5); // Bonus Ship (not confirmed) - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_screen_red = data & 0x04; @@ -233,15 +233,16 @@ void _8080bw_state::lrescue_sh_port_1_w(uint8_t data) void _8080bw_state::lrescue_sh_port_2_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_2_last_extra; + uint8_t falling_bits = ~data & m_port_2_last_extra; - if (rising_bits & 0x01) m_samples->start(1, 8); /* Footstep high tone */ - if (rising_bits & 0x02) m_samples->start(1, 7); /* Footstep low tone */ - if (rising_bits & 0x04) m_samples->start(1, 4); /* Bonus when counting men saved */ + if (BIT(rising_bits, 0)) m_samples->start(1, 8); // Footstep high tone + if (BIT(rising_bits, 1)) m_samples->start(1, 7); // Footstep low tone + if (BIT(rising_bits, 2)) m_samples->start(1, 4); // Bonus when counting men saved - m_speaker->level_w(BIT(data, 3)); /* Bitstream tunes - endlevel and bonus1 */ + m_speaker->level_w(BIT(data, 3)); // Bitstream tunes - endlevel and bonus1 - if (rising_bits & 0x10) m_samples->start(3, 6); /* Shooting Star and Rescue Ship sounds */ - if ((~data & 0x10) && (m_port_2_last_extra & 0x10)) m_samples->stop(3); /* This makes the rescue ship sound beep on and off */ + if (BIT(rising_bits, 4)) m_samples->start(3, 6); // Shooting Star and Rescue Ship sounds + if (BIT(falling_bits, 4)) m_samples->stop(3); // This makes the rescue ship sound beep on and off m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); @@ -324,13 +325,13 @@ void _8080bw_state::ballbomb_sh_port_1_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - if (rising_bits & 0x01) m_samples->start(1, 2); /* Hit a balloon */ - if (rising_bits & 0x02) m_samples->start(2, 0); /* Shot Sound */ - if (rising_bits & 0x04) m_samples->start(2, 1); /* Base Hit */ - if (rising_bits & 0x08) m_samples->start(1, 7); /* Hit a Bomb */ - if (rising_bits & 0x10) m_samples->start(3, 8); /* Bonus Base at 1500 points */ + if (BIT(rising_bits, 0)) m_samples->start(1, 2); // Hit a balloon + if (BIT(rising_bits, 1)) m_samples->start(2, 0); // Shot Sound + if (BIT(rising_bits, 2)) m_samples->start(2, 1); // Base Hit + if (BIT(rising_bits, 3)) m_samples->start(1, 7); // Hit a Bomb + if (BIT(rising_bits, 4)) m_samples->start(3, 8); // Bonus Base at 1500 points - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_screen_red = data & 0x04; @@ -341,9 +342,9 @@ void _8080bw_state::ballbomb_sh_port_2_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_2_last_extra; - if (data & 0x01) m_samples->start(0, 7); /* Indicates plane will drop bombs */ - if (data & 0x04) m_samples->start(0, 4); /* Plane is dropping new balloons at start of level */ - if (rising_bits & 0x10) m_samples->start(2, 2); /* Balloon hit and bomb drops */ + if (BIT(data, 0)) m_samples->start(0, 7); // Indicates plane will drop bombs + if (BIT(data, 2)) m_samples->start(0, 4); // Plane is dropping new balloons at start of level + if (BIT(rising_bits, 4)) m_samples->start(2, 2); // Balloon hit and bomb drops m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); @@ -400,12 +401,12 @@ void _8080bw_state::indianbt_sh_port_1_w(uint8_t data) /* bit 4 occurs every 5.25 seconds during gameplay */ uint8_t rising_bits = data & ~m_port_1_last_extra; - if (rising_bits & 0x01) m_samples->start(1, 7); /* Death */ - if (rising_bits & 0x02) m_samples->start(0, 1); /* Shot Sound */ - if (rising_bits & 0x04) m_samples->start(2, 3); /* Move */ - if (rising_bits & 0x08) m_samples->start(3, 2); /* Hit */ + if (BIT(rising_bits, 0)) m_samples->start(1, 7); // Death + if (BIT(rising_bits, 1)) m_samples->start(0, 1); // Shot Sound + if (BIT(rising_bits, 2)) m_samples->start(2, 3); // Move + if (BIT(rising_bits, 3)) m_samples->start(3, 2); // Hit - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_port_1_last_extra = data; } @@ -414,10 +415,10 @@ void _8080bw_state::indianbt_sh_port_2_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_2_last_extra; - if (rising_bits & 0x01) m_samples->start(4, 0); /* Bird dropped an egg, Lasso used */ - if (rising_bits & 0x02) m_samples->start(4, 2); /* Egg hatches, egg shot */ - if (rising_bits & 0x08) m_samples->start(5, 0); /* Grabber, Lasso caught something */ - if (rising_bits & 0x10) m_samples->start(3, 7); /* Lasso sound */ + if (BIT(rising_bits, 0)) m_samples->start(4, 0); // Bird dropped an egg, Lasso used + if (BIT(rising_bits, 1)) m_samples->start(4, 2); // Egg hatches, egg shot + if (BIT(rising_bits, 3)) m_samples->start(5, 0); // Grabber, Lasso caught something + if (BIT(rising_bits, 4)) m_samples->start(3, 7); // Lasso sound m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); @@ -433,11 +434,11 @@ void _8080bw_state::indianbtbr_sh_port_1_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - if (rising_bits & 0x01) m_samples->start(4, 7); /* Lasso */ - if (rising_bits & 0x04) m_samples->start(0, 1); /* Shot Sound */ - if (rising_bits & 0x08) m_samples->start(3, 2); /* Hit */ + if (BIT(rising_bits, 0)) m_samples->start(4, 7); // Lasso + if (BIT(rising_bits, 2)) m_samples->start(0, 1); // Shot Sound + if (BIT(rising_bits, 3)) m_samples->start(3, 2); // Hit - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_port_1_last_extra = data; } @@ -446,8 +447,8 @@ void _8080bw_state::indianbtbr_sh_port_2_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_2_last_extra; - if (rising_bits & 0x08) m_samples->start(2, 3); /* Move */ - if (rising_bits & 0x10) m_samples->start(3, 7); /* Death */ + if (BIT(rising_bits, 3)) m_samples->start(2, 3); // Move + if (BIT(rising_bits, 4)) m_samples->start(3, 7); // Death m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); @@ -999,7 +1000,7 @@ void _8080bw_state::schaser_sh_port_2_w(uint8_t data) m_discrete->write(SCHASER_MUSIC_BIT, BIT(data, 0)); m_discrete->write(SCHASER_SND_EN, BIT(data, 1)); - machine().sound().system_enable(BIT(data, 1)); + machine().sound().system_mute(!BIT(data, 1)); machine().bookkeeping().coin_lockout_global_w(BIT(data, 2)); @@ -1110,9 +1111,9 @@ void _8080bw_state::rollingc_sh_port_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_3_last_extra; - if (rising_bits & 0x02) m_samples->start(4, 0); /* Steering */ - if (rising_bits & 0x04) m_samples->start(0, 1); /* Collision */ - if (rising_bits & 0x10) m_samples->start(1, 8); /* Computer car is starting to move */ + if (BIT(rising_bits, 1)) m_samples->start(4, 0); // Steering + if (BIT(rising_bits, 2)) m_samples->start(0, 1); // Collision + if (BIT(rising_bits, 4)) m_samples->start(1, 8); // Computer car is starting to move m_port_3_last_extra = data; } @@ -1127,13 +1128,13 @@ void _8080bw_state::rollingc_sh_port_w(uint8_t data) const char *const lupin3_sample_names[] = { "*lupin3", - "cap", /* go to jail */ - "bark", /* dog barking */ - "walk1", /* walk, get money */ - "walk2", /* walk, get money */ - "warp", /* translocate, deposit money */ - "extend", /* bonus man */ - "kick", /* lands on top of building, wife kicks man */ + "cap", // go to jail + "bark", // dog barking + "walk1", // walk, get money + "walk2", // walk, get money + "warp", // translocate, deposit money + "extend", // bonus man + "kick", // lands on top of building, wife kicks man nullptr }; @@ -1147,21 +1148,21 @@ void _8080bw_state::lupin3_sh_port_1_w(uint8_t data) uint8_t rising_bits = data & ~m_port_1_last_extra; static uint8_t lupin3_step = 2; - if (rising_bits & 0x01) + if (BIT(rising_bits, 0)) { - m_samples->start(0, lupin3_step); /* Walking, steal money */ + m_samples->start(0, lupin3_step); // Walking, steal money lupin3_step ^= 1; } - m_sn->enable_w(data & 0x02 ? 0:1); /* Helicopter */ + m_sn->enable_w(BIT(~data, 1)); // Helicopter - if (rising_bits & 0x04) m_samples->start(1, 4); /* Translocate */ - if (rising_bits & 0x08) m_samples->start(0, 0); /* Jail */ - if (rising_bits & 0x10) m_samples->start(2, 5); /* Bonus Man */ + if (BIT(rising_bits, 2)) m_samples->start(1, 4); // Translocate + if (BIT(rising_bits, 3)) m_samples->start(0, 0); // Jail + if (BIT(rising_bits, 4)) m_samples->start(2, 5); // Bonus Man - //machine().sound().system_enable(data & 0x20); + //machine().sound().system_mute(!BIT(data, 5)); - //machine().bookkeeping().coin_lockout_global_w(data & 0x80); + //machine().bookkeeping().coin_lockout_global_w(BIT(data, 7)); m_port_1_last_extra = data; } @@ -1198,17 +1199,17 @@ void _8080bw_state::schasercv_sh_port_1_w(uint8_t data) uint8_t rising_bits = data & ~m_port_1_last_extra; - if (rising_bits & 0x02) m_samples->start(1, 6); /* Ran over a dot */ - if (rising_bits & 0x10) m_samples->start(0, 1); /* Death */ + if (BIT(rising_bits, 1)) m_samples->start(1, 6); // Ran over a dot + if (BIT(rising_bits, 4)) m_samples->start(0, 1); // Death m_port_1_last_extra = data; } void _8080bw_state::schasercv_sh_port_2_w(uint8_t data) { - m_speaker->level_w(BIT(data, 0)); /* End-of-Level */ + m_speaker->level_w(BIT(data, 0)); // End-of-Level - machine().sound().system_enable(data & 0x10); + machine().sound().system_mute(!BIT(data, 4)); m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); } @@ -1229,8 +1230,8 @@ void _8080bw_state::crashrd_port03_w(uint8_t data) bit 4 - Dot Sound Enable (SX0) bit 5 - Effect Sound C (SX4) */ - m_discrete->write(SCHASER_SND_EN, BIT(data,5)); - machine().sound().system_enable(BIT(data,5)); + m_discrete->write(SCHASER_SND_EN, BIT(data, 5)); + machine().sound().system_mute(!BIT(data, 5)); m_discrete->write(SCHASER_DOT_EN, BIT(data, 4)); m_discrete->write(SCHASER_DOT_SEL, BIT(data, 0)); @@ -1302,13 +1303,13 @@ void _8080bw_state::yosakdon_sh_port_1_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - if (rising_bits & 0x01) m_samples->start(0, 3); /* Game Over */ - if (rising_bits & 0x02) m_samples->start(2, 0); /* Bird dead */ - if (rising_bits & 0x04) m_samples->start(0, 1); /* Rifle being fired */ - if (rising_bits & 0x08) m_samples->start(1, 2); /* Man dead */ - if (rising_bits & 0x10) m_samples->start(5, 8); /* Bonus Man? */ + if (BIT(rising_bits, 0)) m_samples->start(0, 3); // Game Over + if (BIT(rising_bits, 1)) m_samples->start(2, 0); // Bird dead + if (BIT(rising_bits, 2)) m_samples->start(0, 1); // Rifle being fired + if (BIT(rising_bits, 3)) m_samples->start(1, 2); // Man dead + if (BIT(rising_bits, 4)) m_samples->start(5, 8); // Bonus Man? - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_port_1_last_extra = data; } @@ -1317,12 +1318,12 @@ void _8080bw_state::yosakdon_sh_port_2_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_2_last_extra; - if (rising_bits & 0x01) m_samples->start(1, 6); /* Ready? , Game Over */ - if (rising_bits & 0x04) m_samples->start(3, 7); /* Big bird dead */ + if (BIT(rising_bits, 0)) m_samples->start(1, 6); // Ready? , Game Over + if (BIT(rising_bits, 2)) m_samples->start(3, 7); // Big bird dead - m_sn->enable_w(data & 0x08 ? 0:1); /* Big bird */ + m_sn->enable_w(BIT(~data, 3)); // Big bird - if (rising_bits & 0x10) m_samples->start(2, 7); /* Game Over */ + if (BIT(rising_bits, 4)) m_samples->start(2, 7); // Game Over m_flip_screen = BIT(data, 5) & ioport(CABINET_PORT_TAG)->read(); @@ -1386,20 +1387,20 @@ void _8080bw_state::darthvdr_08_w(uint8_t data) { uint8_t rising_bits = data & ~m_port_1_last_extra; - machine().sound().system_enable(data & 0x01); + machine().sound().system_mute(!BIT(data, 0)); - if (rising_bits & 0x02) m_samples->start(0, 0); /* Shoot */ - if (rising_bits & 0x04) m_samples->start(3, 7); /* Hit UFO */ - if (rising_bits & 0x10) m_samples->start(5, 8); /* Bonus */ + if (BIT(rising_bits, 1)) m_samples->start(0, 0); // Shoot + if (BIT(rising_bits, 2)) m_samples->start(3, 7); // Hit UFO + if (BIT(rising_bits, 4)) m_samples->start(5, 8); // Bonus - m_sn->enable_w(data & 0x20 ? 0:1); /* UFO */ + m_sn->enable_w(BIT(~data, 5)); // UFO - if (rising_bits & 0x40) m_samples->start(1, 1); /* Death */ - if (rising_bits & 0x80) m_samples->start(2, 2); /* Hit */ + if (BIT(rising_bits, 6)) m_samples->start(1, 1); // Death + if (BIT(rising_bits, 7)) m_samples->start(2, 2); // Hit - if (rising_bits & 0x08) + if (BIT(rising_bits, 3)) { - m_samples->start(4, m_fleet_step); /* Fleet move in 4 steps */ + m_samples->start(4, m_fleet_step); // Fleet move in 4 steps m_fleet_step++; if (m_fleet_step > 6) m_fleet_step = 3; } diff --git a/src/mame/audio/astrof.cpp b/src/mame/audio/astrof.cpp index 63ea0bdf085..b9d141c698c 100644 --- a/src/mame/audio/astrof.cpp +++ b/src/mame/audio/astrof.cpp @@ -72,7 +72,7 @@ void astrof_state::astrof_audio_1_w(uint8_t data) /* D6 - don't know. Probably something to do with the explosion sounds */ /* D7 - sound enable bit */ - machine().sound().system_enable(data & 0x80); + machine().sound().system_mute(!BIT(data, 7)); m_port_1_last = data; } @@ -193,7 +193,7 @@ void astrof_state::tomahawk_audio_w(uint8_t data) /* D6 - explosion */ /* D7 - sound enable bit */ - machine().sound().system_enable(data & 0x80); + machine().sound().system_mute(!BIT(data, 7)); } diff --git a/src/mame/audio/bzone.cpp b/src/mame/audio/bzone.cpp index ebd483d14a1..6e88b655672 100644 --- a/src/mame/audio/bzone.cpp +++ b/src/mame/audio/bzone.cpp @@ -393,7 +393,7 @@ void bzone_state::bzone_sounds_w(uint8_t data) m_discrete->write(BZ_INPUT, data); m_startled = BIT(data, 6); - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); } void bzone_state::bzone_audio(machine_config &config) diff --git a/src/mame/audio/mw8080bw.cpp b/src/mame/audio/mw8080bw.cpp index 28c7320a7a4..ca5f90b22c9 100644 --- a/src/mame/audio/mw8080bw.cpp +++ b/src/mame/audio/mw8080bw.cpp @@ -1615,7 +1615,7 @@ void gmissile_audio_device::p1_w(u8 data) machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); - machine().sound().system_enable(BIT(data, 3)); + machine().sound().system_mute(!BIT(data, 3)); if (BIT(rising, 4)) m_samples[1]->start(0, 0); // RIGHT MISSILE sound (goes to right speaker) @@ -1710,7 +1710,7 @@ void m4_audio_device::p1_w(u8 data) machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); - machine().sound().system_enable(BIT(data, 3)); + machine().sound().system_mute(!BIT(data, 3)); if (BIT(rising, 4)) m_samples[0]->start(0, 0); // LEFT PLAYER SHOT sound (goes to left speaker) if (BIT(rising, 5)) m_samples[1]->start(0, 0); // RIGHT PLAYER SHOT sound (goes to right speaker) @@ -1977,7 +1977,7 @@ void clowns_audio_device::p2_w(u8 data) m_discrete->write(CLOWNS_POP_MIDDLE_EN, BIT(data, 1)); m_discrete->write(CLOWNS_POP_TOP_EN, BIT(data, 2)); - machine().sound().system_enable(BIT(data, 3)); + machine().sound().system_mute(!BIT(data, 3)); m_discrete->write(CLOWNS_SPRINGBOARD_HIT_EN, BIT(data, 4)); @@ -2365,7 +2365,7 @@ void spacwalk_audio_device::p1_w(u8 data) if (BIT(changed, 1)) m_ctrl_sel_out(BIT(data, 1)); - machine().sound().system_enable(BIT(data, 2)); + machine().sound().system_mute(!BIT(data, 2)); m_discrete->write(SPACWALK_SPACE_SHIP_EN, (data >> 3) & 0x01); } @@ -2550,7 +2550,7 @@ void dogpatch_audio_device::write(u8 data) machine().bookkeeping().coin_counter_w(0, BIT(data, 2)); - machine().sound().system_enable(BIT(data, 3)); + machine().sound().system_mute(!BIT(data, 3)); m_discrete->write(DOGPATCH_GAME_ON_EN, BIT(data, 3)); m_discrete->write(DOGPATCH_LEFT_SHOT_EN, BIT(data, 4)); @@ -3043,7 +3043,7 @@ spcenctr_audio_device::spcenctr_audio_device(machine_config const &mconfig, char void spcenctr_audio_device::p1_w(u8 data) { - machine().sound().system_enable(BIT(data, 0)); + machine().sound().system_mute(!BIT(data, 0)); // D1 is marked as 'OPTIONAL SWITCH VIDEO FOR COCKTAIL', but it is never set by the software @@ -3154,8 +3154,10 @@ void phantom2_audio_device::p1_w(u8 data) // if (data & 0x02) enable ENEMY SHOT sound - machine().sound().system_mute(!BIT(data, 5)); - machine().sound().system_enable(BIT(data, 2)); + // previously, code did this - system_mute and system_enable controlled the same thing, so bit 5 was ignored + //machine().sound().system_mute(!BIT(data, 5)); + //machine().sound().system_enable(BIT(data, 2)); + machine().sound().system_mute(!BIT(data, 5) && !BIT(data, 2)); machine().bookkeeping().coin_counter_w(0, BIT(data, 3)); @@ -3275,7 +3277,7 @@ void invaders_audio_device::p1_w(u8 data) m_discrete->write(INVADERS_NODE(INVADERS_INVADER_HIT_EN, 1), data & 0x08); m_discrete->write(INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, 1), data & 0x10); - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); // D6 and D7 are not connected } @@ -3471,7 +3473,7 @@ void invad2ct_audio_device::p1_w(u8 data) m_discrete->write(INVADERS_NODE(INVADERS_INVADER_HIT_EN, 1), data & 0x08); m_discrete->write(INVADERS_NODE(INVADERS_BONUS_MISSLE_BASE_EN, 1), data & 0x10); - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); // D6 and D7 are not connected } @@ -4209,7 +4211,7 @@ void mw8080bw_state::checkmat_audio_w(uint8_t data) machine().bookkeeping().coin_counter_w(0, (data >> 2) & 0x01); - machine().sound().system_enable((data >> 3) & 0x01); + machine().sound().system_mute(!BIT(data, 3)); m_discrete->write(CHECKMAT_TONE_DATA_45, (data >> 4) & 0x03); m_discrete->write(CHECKMAT_TONE_DATA_67, (data >> 6) & 0x03); @@ -4425,7 +4427,7 @@ void mw8080bw_state::shuffle_audio_1_w(uint8_t data) m_discrete->write(SHUFFLE_ROLLOVER_EN, (data >> 1) & 0x01); - machine().sound().system_enable((data >> 2) & 0x01); + machine().sound().system_mute(!BIT(data, 2)); m_discrete->write(NODE_29, (data >> 3) & 0x07); @@ -4542,7 +4544,7 @@ void mw8080bw_state::bowler_audio_1_w(uint8_t data) machine().bookkeeping().coin_counter_w(0, (data >> 1) & 0x01); - machine().sound().system_enable((data >> 2) & 0x01); + machine().sound().system_mute(!BIT(data, 2)); m_discrete->write(BOWLER_FOWL_EN, (data >> 3) & 0x01); diff --git a/src/mame/audio/turbo.cpp b/src/mame/audio/turbo.cpp index 42eec15bb6e..66867a6e0cd 100644 --- a/src/mame/audio/turbo.cpp +++ b/src/mame/audio/turbo.cpp @@ -547,7 +547,7 @@ void turbo_state::buckrog_sound_b_w(u8 data) if ((diff & 0x40) && !(data & 0x40) && m_samples->playing(5)) m_samples->stop(5); /* GAME ON */ - machine().sound().system_enable(data & 0x80); + machine().sound().system_mute(!BIT(data, 7)); } diff --git a/src/mame/drivers/alinvade.cpp b/src/mame/drivers/alinvade.cpp index a13baceb064..932c1cd87b3 100644 --- a/src/mame/drivers/alinvade.cpp +++ b/src/mame/drivers/alinvade.cpp @@ -87,7 +87,7 @@ void alinvade_state::sound_w(uint8_t data) void alinvade_state::sounden_w(uint8_t data) { - machine().sound().system_enable(data == 4); + machine().sound().system_mute(data != 4); } uint8_t alinvade_state::irqmask_r() diff --git a/src/mame/drivers/astinvad.cpp b/src/mame/drivers/astinvad.cpp index 86d1dc1502f..e3427f01480 100644 --- a/src/mame/drivers/astinvad.cpp +++ b/src/mame/drivers/astinvad.cpp @@ -385,7 +385,7 @@ void astinvad_state::kamikaze_sound1_w(uint8_t data) if (bits_gone_hi & 0x08) m_samples->start(3, SND_INVADERHIT); if (bits_gone_hi & 0x10) m_samples->start(2, SND_BONUS); - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); } void astinvad_state::kamikaze_sound2_w(uint8_t data) @@ -418,7 +418,7 @@ void astinvad_state::spcking2_sound1_w(uint8_t data) if (bits_gone_hi & 0x04) m_samples->start(2, SND_BASEHIT); if (bits_gone_hi & 0x08) m_samples->start(3, SND_INVADERHIT); if (bits_gone_hi & 0x10) m_samples->start(2, SND_BONUS); - machine().sound().system_enable(data & 0x20); + machine().sound().system_mute(!BIT(data, 5)); m_screen_red = data & 0x04; // ? } @@ -465,7 +465,7 @@ void astinvad_state::spaceint_sound2_w(uint8_t data) int bits_gone_hi = data & ~m_sound_state[1]; m_sound_state[1] = data; - machine().sound().system_enable(data & 0x02); + machine().sound().system_mute(!BIT(data, 1)); if (bits_gone_hi & 0x04) m_samples->start(3, SND_INVADERHIT); diff --git a/src/mame/drivers/buggychl.cpp b/src/mame/drivers/buggychl.cpp index 4e625f56f3d..b398cd4e4c9 100644 --- a/src/mame/drivers/buggychl.cpp +++ b/src/mame/drivers/buggychl.cpp @@ -113,7 +113,7 @@ void buggychl_state::sound_enable_w(uint8_t data) // does this really only control the sound irq 'timer' enable state, rather than the entire sound system? // this would be more in line with the (admittedly incorrect) schematic... //logerror("Sound_enable_w written with data of %02x\n", data); - machine().sound().system_enable(data & 1); + machine().sound().system_mute(!BIT(data, 0)); } uint8_t buggychl_state::mcu_status_r() diff --git a/src/mame/drivers/crbaloon.cpp b/src/mame/drivers/crbaloon.cpp index a5cbfa64982..f2f5a45bde2 100644 --- a/src/mame/drivers/crbaloon.cpp +++ b/src/mame/drivers/crbaloon.cpp @@ -157,29 +157,29 @@ uint8_t crbaloon_state::pc3259_r(offs_t offset) void crbaloon_state::port_sound_w(uint8_t data) { - /* D0 - interrupt enable - also goes to PC3259 as /HTCTRL */ + // D0 - interrupt enable - also goes to PC3259 as /HTCTRL m_irq_mask = data & 0x01; - crbaloon_set_clear_collision_address((data & 0x01) ? true : false); + crbaloon_set_clear_collision_address(BIT(data, 0)); - /* D1 - SOUND STOP */ - machine().sound().system_enable((data & 0x02) ? true : false); + // D1 - SOUND STOP + machine().sound().system_mute(!BIT(data, 1)); - /* D2 - unlabeled - music enable */ - crbaloon_audio_set_music_enable((data & 0x04) ? true : false); + // D2 - unlabeled - music enable + crbaloon_audio_set_music_enable(BIT(data, 2)); - /* D3 - EXPLOSION */ - crbaloon_audio_set_explosion_enable((data & 0x08) ? true : false); + // D3 - EXPLOSION + crbaloon_audio_set_explosion_enable(BIT(data, 3)); - /* D4 - BREATH */ - crbaloon_audio_set_breath_enable((data & 0x10) ? true : false); + // D4 - BREATH + crbaloon_audio_set_breath_enable(BIT(data, 4)); - /* D5 - APPEAR */ - crbaloon_audio_set_appear_enable((data & 0x20) ? true : false); + // D5 - APPEAR + crbaloon_audio_set_appear_enable(BIT(data, 5)); - /* D6 - unlabeled - laugh enable */ - crbaloon_audio_set_laugh_enable((data & 0x40) ? true : false); + // D6 - unlabeled - laugh enable + crbaloon_audio_set_laugh_enable(BIT(data, 6)); - /* D7 - unlabeled - goes to PC3259 pin 16 */ + // D7 - unlabeled - goes to PC3259 pin 16 pc3259_update(); } diff --git a/src/mame/drivers/darius.cpp b/src/mame/drivers/darius.cpp index 6ef7140a0ec..505f16369ba 100644 --- a/src/mame/drivers/darius.cpp +++ b/src/mame/drivers/darius.cpp @@ -677,7 +677,7 @@ void darius_state::machine_reset() m_adpcm_command = 0; m_nmi_enable = 0; - machine().sound().system_enable(true); /* mixer enabled */ + machine().sound().system_mute(false); /* mixer enabled */ for (auto & elem : m_vol) elem = 0x00; /* min volume */ diff --git a/src/mame/drivers/maxaflex.cpp b/src/mame/drivers/maxaflex.cpp index fdc24aa5c5b..a6730dd10b3 100644 --- a/src/mame/drivers/maxaflex.cpp +++ b/src/mame/drivers/maxaflex.cpp @@ -162,7 +162,7 @@ void maxaflex_state::mcu_portb_w(uint8_t data) m_maincpu->set_input_line(INPUT_LINE_RESET, BIT(data, 4) ? CLEAR_LINE : ASSERT_LINE); /* AUDMUTE */ - machine().sound().system_enable(BIT(data, 5)); + machine().sound().system_mute(!BIT(data, 5)); /* latch for lamps */ if (BIT(diff, 6) && !BIT(data, 6)) diff --git a/src/mame/drivers/ninjaw.cpp b/src/mame/drivers/ninjaw.cpp index d3eecd5df84..e75a55d401a 100644 --- a/src/mame/drivers/ninjaw.cpp +++ b/src/mame/drivers/ninjaw.cpp @@ -696,7 +696,7 @@ void ninjaw_state::machine_reset() memset(m_pandata, 0, sizeof(m_pandata)); /**** mixer control enable ****/ - machine().sound().system_enable(true); /* mixer enabled */ + machine().sound().system_mute(false); /* mixer enabled */ } void ninjaw_state::ninjaw(machine_config &config) diff --git a/src/mame/drivers/rowamet.cpp b/src/mame/drivers/rowamet.cpp index 1a71a368b63..8d48bfb8990 100644 --- a/src/mame/drivers/rowamet.cpp +++ b/src/mame/drivers/rowamet.cpp @@ -179,7 +179,7 @@ uint8_t rowamet_state::sound_r() void rowamet_state::mute_w(uint8_t data) { - machine().sound().system_enable(data ? 0 : 1); + machine().sound().system_mute(data != 0); } uint8_t rowamet_state::io_r(offs_t offset) diff --git a/src/mame/drivers/segahang.cpp b/src/mame/drivers/segahang.cpp index cee6ad4c941..ff7adecdd75 100644 --- a/src/mame/drivers/segahang.cpp +++ b/src/mame/drivers/segahang.cpp @@ -111,7 +111,7 @@ void segahang_state::tilemap_sound_w(uint8_t data) m_segaic16vid->tilemap_set_rowscroll(0, ~data & 0x02); // bit 0: sound mute - machine().sound().system_enable(data & 0x01); + machine().sound().system_mute(!BIT(data, 0)); } diff --git a/src/mame/drivers/segaorun.cpp b/src/mame/drivers/segaorun.cpp index 369dde654a2..afea9021c32 100644 --- a/src/mame/drivers/segaorun.cpp +++ b/src/mame/drivers/segaorun.cpp @@ -692,10 +692,10 @@ void segaorun_state::outrun_custom_io_w(offs_t offset, uint16_t data, uint16_t m // D2: Start lamp // D1: Brake lamp // other bits: ? - machine().sound().system_enable(data & 0x80); - output().set_value("Vibration_motor", data >> 5 & 1); - output().set_value("Start_lamp", data >> 2 & 1); - output().set_value("Brake_lamp", data >> 1 & 1); + machine().sound().system_mute(!BIT(data, 7)); + output().set_value("Vibration_motor", BIT(data, 5)); + output().set_value("Start_lamp", BIT(data, 2)); + output().set_value("Brake_lamp", BIT(data, 1)); } return; diff --git a/src/mame/drivers/segaxbd.cpp b/src/mame/drivers/segaxbd.cpp index 92efade11c1..f6ff0506fab 100644 --- a/src/mame/drivers/segaxbd.cpp +++ b/src/mame/drivers/segaxbd.cpp @@ -526,7 +526,7 @@ void segaxbd_state::pd_0_w(uint8_t data) // Output port: // D7: Amplifier mute control (1= sounding, 0= muted) // D6-D0: CN D pin A17-A23 (output level 1= high, 0= low) - usually set up as lamps and coincounter - machine().sound().system_enable(data & 0x80); + machine().sound().system_mute(!BIT(data, 7)); generic_iochip0_lamps_w(data); } @@ -767,7 +767,7 @@ uint8_t segaxbd_state::lastsurv_port_r() void segaxbd_state::lastsurv_muxer_w(uint8_t data) { - machine().sound().system_enable(data & 0x80); + machine().sound().system_mute(!BIT(data, 7)); m_lastsurv_mux = (data >> 5) & 3; generic_iochip0_lamps_w(data & 0x9f); diff --git a/src/mame/drivers/segaybd.cpp b/src/mame/drivers/segaybd.cpp index f87aa39ff53..3680effcb31 100644 --- a/src/mame/drivers/segaybd.cpp +++ b/src/mame/drivers/segaybd.cpp @@ -147,7 +147,7 @@ void segaybd_state::output2_w(uint8_t data) // D7 = /MUTE // D6-D0 = FLT31-25 - machine().sound().system_enable(data & 0x80); + machine().sound().system_mute(!BIT(data, 7)); } diff --git a/src/mame/drivers/thepit.cpp b/src/mame/drivers/thepit.cpp index bd32f1f54df..68269cc4c11 100644 --- a/src/mame/drivers/thepit.cpp +++ b/src/mame/drivers/thepit.cpp @@ -194,7 +194,7 @@ WRITE_LINE_MEMBER(thepit_state::coin_lockout_w) WRITE_LINE_MEMBER(thepit_state::sound_enable_w) { - machine().sound().system_enable(state); + machine().sound().system_mute(!state); } WRITE_LINE_MEMBER(thepit_state::nmi_mask_w) diff --git a/src/mame/drivers/uapce.cpp b/src/mame/drivers/uapce.cpp index 9016b99689c..f8fb440524a 100644 --- a/src/mame/drivers/uapce.cpp +++ b/src/mame/drivers/uapce.cpp @@ -163,7 +163,7 @@ void uapce_state::jamma_if_control_latch_w(uint8_t data) /* D7 : Controls relay which connects the PCE R-AUDIO output to the common audio path. (1= Relay closed, 0= Relay open) */ - machine().sound().system_enable( (data >> 7) & 1 ); + machine().sound().system_mute(!BIT(data, 7)); /* D6 : Output to JAMMA connector KEY pin. Connected to /RESET on the PCE backplane connector. (1= /RESET not asserted, 0= /RESET asserted) */ diff --git a/src/mame/drivers/warriorb.cpp b/src/mame/drivers/warriorb.cpp index e6e013fcf1b..baf1e0e4dd7 100644 --- a/src/mame/drivers/warriorb.cpp +++ b/src/mame/drivers/warriorb.cpp @@ -395,7 +395,7 @@ void warriorb_state::machine_start() void warriorb_state::machine_reset() { /**** mixer control enable ****/ - machine().sound().system_enable(true); /* mixer enabled */ + machine().sound().system_mute(false); /* mixer enabled */ } void warriorb_state::darius2d(machine_config &config) diff --git a/src/mame/layout/mdndclab.lay b/src/mame/layout/mdndclab.lay index 1f3b68a26e0..7cc3b69103e 100644 --- a/src/mame/layout/mdndclab.lay +++ b/src/mame/layout/mdndclab.lay @@ -20,7 +20,7 @@ license:CC0 local last_state = false local function get_mouse() - local x, y, button, target = machine:uiinput():find_mouse() + local x, y, button, target = machine.uiinput:find_mouse() if not button then last_state = false return nil @@ -34,7 +34,7 @@ license:CC0 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 machine.options.entries.keepaspect:value() then if (vh / h) < (vw / w) then local oh = h h = w * (vh / vw) @@ -54,12 +54,12 @@ license:CC0 function layout.reset() for num, col in pairs(walls) do for num2, wall in pairs(col[2]) do - machine:outputs():set_indexed_value("colwall", (num * 10) + num2, 0) + machine.output:set_indexed_value("colwall", (num * 10) + num2, 0) end end for num, row in pairs(walls) do for num2, wall in pairs(row[2]) do - machine:outputs():set_indexed_value("rowwall", (num * 10) + num2, 0) + machine.output:set_indexed_value("rowwall", (num * 10) + num2, 0) end end end @@ -73,8 +73,8 @@ license:CC0 if col[1] < x and (col[1] + 2.5) > x then for num2, wall in pairs(col[2]) do if wall < y and (wall + 7.5) > y then - local state = machine:outputs():get_indexed_value("colwall", (num * 10) + num2) - machine:outputs():set_indexed_value("colwall", (num * 10) + num2, (~state) & 1) + local state = machine.output:get_indexed_value("colwall", (num * 10) + num2) + machine.output:set_indexed_value("colwall", (num * 10) + num2, (~state) & 1) return end end @@ -84,8 +84,8 @@ license:CC0 if row[1] < y and (row[1] + 2.5) > y then for num2, wall in pairs(row[2]) do if wall < x and (wall + 7.5) > x then - local state = machine:outputs():get_indexed_value("rowwall", (num * 10) + num2) - machine:outputs():set_indexed_value("rowwall", (num * 10) + num2, (~state) & 1) + local state = machine.output:get_indexed_value("rowwall", (num * 10) + num2) + machine.output:set_indexed_value("rowwall", (num * 10) + num2, (~state) & 1) return end end diff --git a/src/mame/layout/v4dbltak.lay b/src/mame/layout/v4dbltak.lay index 55d6f5345db..98a40e15f4e 100644 --- a/src/mame/layout/v4dbltak.lay +++ b/src/mame/layout/v4dbltak.lay @@ -23,7 +23,7 @@ license:CC0 for ledno, lamps in pairs(ledlamps) do local ledstate = 0 for bit, lampno in pairs(lamps) do - if machine:outputs():get_indexed_value("lamp", lampno) > 0 then + if machine.output:get_indexed_value("lamp", lampno) > 0 then ledstate = ledstate | (1 << (bit - 1)) end end diff --git a/src/mame/tiny.lst b/src/mame/tiny.lst index 51014c2aff6..3ab2084a471 100644 --- a/src/mame/tiny.lst +++ b/src/mame/tiny.lst @@ -22,6 +22,7 @@ hardhat // (c) 1982 fax // (c) 1983 fax2 // (c) 1983 circus // (c) 1977 Exidy +circuso // (c) 1977 Exidy robotbwl // (c) 197? Exidy crash // (c) 1979 Exidy ripcord // (c) 1979 Exidy diff --git a/src/mame/video/dday.cpp b/src/mame/video/dday.cpp index 71b6c51297d..3643fb5e793 100644 --- a/src/mame/video/dday.cpp +++ b/src/mame/video/dday.cpp @@ -278,7 +278,7 @@ void dday_state::dday_control_w(uint8_t data) if (!(data & 0x10) && (m_control & 0x10)) m_ay1->reset(); - machine().sound().system_enable(data & 0x10); + machine().sound().system_mute(!BIT(data, 4)); /* bit 6 is search light enable */ m_sl_enable = data & 0x40; |