diff options
| author | 2026-02-09 10:26:40 -0800 | |
|---|---|---|
| committer | 2026-02-09 19:26:40 +0100 | |
| commit | 6b6fd5cdce494fb7474f79cf0c8eba14982190d2 (patch) | |
| tree | de6b387b861fc4946ce34964641313b51dedb60d /src | |
| parent | d24b0cf898d1759c746593af1c9d461705c5d6a8 (diff) | |
Added LUA bindings for vector-screen interfaces.
- screen.cpp: Added a callback mechanism to expose vector drawing to the LUA interface, allowing external hardware devices to interface with MAME's vector rendering code. [Dave Plummer]
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/video/vector.cpp | 38 | ||||
| -rw-r--r-- | src/devices/video/vector.h | 27 | ||||
| -rw-r--r-- | src/frontend/mame/luaengine.cpp | 32 |
3 files changed, 97 insertions, 0 deletions
diff --git a/src/devices/video/vector.cpp b/src/devices/video/vector.cpp index aa0210eda28..9c0bb682d32 100644 --- a/src/devices/video/vector.cpp +++ b/src/devices/video/vector.cpp @@ -60,6 +60,10 @@ float vector_options::s_beam_width_max = 0.0f; float vector_options::s_beam_dot_size = 0.0f; float vector_options::s_beam_intensity_weight = 0.0f; +namespace { + vector_device::hook_callback s_hook_callback; +} + void vector_options::init(emu_options& options) { s_beam_width_min = options.beam_width_min(); @@ -147,6 +151,11 @@ void vector_device::clear_list(void) m_vector_index = 0; } +void vector_device::set_hook_callback(hook_callback callback) +{ + s_hook_callback = std::move(callback); +} + uint32_t vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { @@ -166,6 +175,12 @@ uint32_t vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma screen.container().empty(); screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTORBUF(1)); + if (s_hook_callback) + { + hook_data begin = { hook_event::FRAME_BEGIN, 0, 0, 0, 0, rgb_t(0xff, 0x00, 0x00, 0x00), 0, visarea.width(), visarea.height() }; + s_hook_callback(machine(), begin); + } + for (int i = 0; i < m_vector_index; i++) { render_bounds coords; @@ -199,11 +214,34 @@ uint32_t vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma flags); } + if (s_hook_callback) + { + hook_data point_data = + { + (curpoint->intensity != 0) ? hook_event::LINE_TO : hook_event::MOVE_TO, + lastx, + lasty, + curpoint->x, + curpoint->y, + curpoint->col, + curpoint->intensity, + visarea.width(), + visarea.height() + }; + s_hook_callback(machine(), point_data); + } + lastx = curpoint->x; lasty = curpoint->y; curpoint++; } + if (s_hook_callback) + { + hook_data end = { hook_event::FRAME_END, 0, 0, 0, 0, rgb_t(0xff, 0x00, 0x00, 0x00), 0, visarea.width(), visarea.height() }; + s_hook_callback(machine(), end); + } + return 0; } diff --git a/src/devices/video/vector.h b/src/devices/video/vector.h index 46731de11a1..bb2c95f62e1 100644 --- a/src/devices/video/vector.h +++ b/src/devices/video/vector.h @@ -5,8 +5,11 @@ #pragma once +#include <functional> + class vector_device; +class running_machine; class vector_options { @@ -30,11 +33,35 @@ public: template <typename T> static constexpr rgb_t color222(T c) { return rgb_t(pal2bit(c >> 4), pal2bit(c >> 2), pal2bit(c >> 0)); } template <typename T> static constexpr rgb_t color444(T c) { return rgb_t(pal4bit(c >> 8), pal4bit(c >> 4), pal4bit(c >> 0)); } + enum class hook_event + { + FRAME_BEGIN, + MOVE_TO, + LINE_TO, + FRAME_END + }; + + struct hook_data + { + hook_event event; + int x0; + int y0; + int x1; + int y1; + rgb_t color; + int intensity; + int width; + int height; + }; + + using hook_callback = std::function<void (running_machine &, hook_data const &)>; + // construction/destruction vector_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void clear_list(); + static void set_hook_callback(hook_callback callback); void add_point(int x, int y, rgb_t color, int intensity); diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 17bdc819538..bacb788c54f 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -17,6 +17,7 @@ #include "ui/ui.h" #include "imagedev/cassette.h" +#include "video/vector.h" #include "debugger.h" #include "drivenum.h" @@ -818,6 +819,10 @@ void lua_engine::initialize() * emu.register_frame_done(callback) - register callback after frame is drawn to screen (for overlays) * emu.register_sound_update(callback) - register callback after sound update has generated new samples * emu.register_periodic(callback) - register periodic callback while program is running + * emu.register_vector_begin(callback) - register callback before each vector screen render + * emu.register_vector_move_to(callback) - register callback for each vector move operation + * emu.register_vector_line_to(callback) - register callback for each vector line operation + * emu.register_vector_end(callback) - register callback after each vector screen render * emu.register_callback(callback, name) - register callback to be used by MAME via lua_engine::call_plugin() * emu.register_menu(event_callback, populate_callback, name) - register callbacks for plugin menu * emu.register_mandatory_file_manager_override(callback) - register callback invoked to override mandatory file manager @@ -831,6 +836,28 @@ void lua_engine::initialize() */ sol::table emu = sol().create_named_table("emu"); + vector_device::set_hook_callback( + [this] (running_machine &machine, vector_device::hook_data const &data) + { + if (!m_machine || (&machine != m_machine)) + return; + + switch (data.event) + { + case vector_device::hook_event::FRAME_BEGIN: + execute_function("LUA_ON_VECTOR_BEGIN", data.width, data.height); + break; + case vector_device::hook_event::MOVE_TO: + execute_function("LUA_ON_VECTOR_MOVE_TO", data.x1, data.y1); + break; + case vector_device::hook_event::LINE_TO: + execute_function("LUA_ON_VECTOR_LINE_TO", data.x0, data.y0, data.x1, data.y1, data.intensity, uint32_t(data.color)); + break; + case vector_device::hook_event::FRAME_END: + execute_function("LUA_ON_VECTOR_END"); + break; + } + }); emu["wait"] = sol::yielding( [this] (sol::this_state s, sol::object duration, sol::variadic_args args) { @@ -940,6 +967,10 @@ void lua_engine::initialize() emu["register_frame_done"] = [this] (sol::function func) { register_function(func, "LUA_ON_FRAME_DONE"); }; emu["register_sound_update"] = [this] (sol::function func) { register_function(func, "LUA_ON_SOUND_UPDATE"); }; emu["register_periodic"] = [this] (sol::function func) { register_function(func, "LUA_ON_PERIODIC"); }; + emu["register_vector_begin"] = [this] (sol::function func) { register_function(func, "LUA_ON_VECTOR_BEGIN"); }; + emu["register_vector_move_to"] = [this] (sol::function func) { register_function(func, "LUA_ON_VECTOR_MOVE_TO"); }; + emu["register_vector_line_to"] = [this] (sol::function func) { register_function(func, "LUA_ON_VECTOR_LINE_TO"); }; + emu["register_vector_end"] = [this] (sol::function func) { register_function(func, "LUA_ON_VECTOR_END"); }; emu["register_mandatory_file_manager_override"] = [this] (sol::function func) { register_function(func, "LUA_ON_MANDATORY_FILE_MANAGER_OVERRIDE"); }; emu["register_before_load_settings"] = [this](sol::function func) { register_function(func, "LUA_ON_BEFORE_LOAD_SETTINGS"); }; emu["register_menu"] = @@ -2266,6 +2297,7 @@ bool lua_engine::frame_hook() void lua_engine::close() { + vector_device::set_hook_callback(vector_device::hook_callback()); m_notifiers.reset(); m_menu.clear(); m_update_tasks.clear(); |
