From 5bb3e2d8c17e0cafc6c3069b6dd2239fbc939c70 Mon Sep 17 00:00:00 2001 From: feos Date: Wed, 10 Jul 2019 22:33:04 +0300 Subject: [PATCH 1/2] luaengine: video:size(), video:pixels(), screen:refresh_attoseconds() pixels() and size() correspond to internal game resolution covering all screens and internal pixel colors. the same values are used for bitmap dumping. similar things available for screen_device lua library take into account final UI resolution and colors, so they can't be used when accurate framebuffer is needed. refresh_attoseconds() allows to calculate precise numerator and denominator for framerate --- src/emu/video.cpp | 40 +++++++++++++++++++++++++++++---- src/emu/video.h | 2 ++ src/frontend/mame/luaengine.cpp | 28 +++++++++++++++++++---- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/emu/video.cpp b/src/emu/video.cpp index f967ef78935..302a3d1c816 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -1266,10 +1266,8 @@ void video_manager::create_snapshot_bitmap(screen_device *screen) } // get the minimum width/height and set it on the target - s32 width = m_snap_width; - s32 height = m_snap_height; - if (width == 0 || height == 0) - m_snap_target->compute_minimum_size(width, height); + 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 @@ -1287,6 +1285,40 @@ void video_manager::create_snapshot_bitmap(screen_device *screen) } +//------------------------------------------------- +// compute_snapshot_size - computes width and +// height of the current snapshot target +// accounting for OPTION_SNAPSIZE +//------------------------------------------------- + +void video_manager::compute_snapshot_size(s32 &width, s32 &height) +{ + width = m_snap_width; + height = m_snap_height; + if (width == 0 || height == 0) + m_snap_target->compute_minimum_size(width, height); +} + + +//------------------------------------------------- +// pixels - fills the specified buffer with the +// RGB values of each pixel in the snapshot target +//------------------------------------------------- + +void video_manager::pixels(u32 *buffer) +{ + create_snapshot_bitmap(nullptr); + for (int y = 0; y < m_snap_bitmap.height(); y++) + { + const u32 *src = &m_snap_bitmap.pix(y, 0); + for (int x = 0; x < m_snap_bitmap.width(); x++) + { + *buffer++ = *src++; + } + } +} + + //------------------------------------------------- // open_next - open the next non-existing file of // type filetype according to our numbering diff --git a/src/emu/video.h b/src/emu/video.h index 4c73db42393..b0a67402424 100644 --- a/src/emu/video.h +++ b/src/emu/video.h @@ -73,6 +73,8 @@ public: void toggle_record_mng() { toggle_record_movie(MF_MNG); } void toggle_record_avi() { toggle_record_movie(MF_AVI); } osd_file::error open_next(emu_file &file, const char *extension, uint32_t index = 0); + void compute_snapshot_size(s32 &width, s32 &height); + void pixels(u32 *buffer); // render a frame void frame_update(bool from_debugger = false); diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 80706f0b7f5..e761b79dae4 100755 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -1819,7 +1819,9 @@ void lua_engine::initialize() * 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() + * 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 @@ -1848,6 +1850,22 @@ void lua_engine::initialize() "speed_factor", &video_manager::speed_factor, "speed_percent", &video_manager::speed_percent, "frame_update", &video_manager::frame_update, + "size", [this](video_manager &vm) { + s32 width, height; + vm.compute_snapshot_size(width, height); + return std::tuple(width, height); + }, + "pixels", [this](video_manager &vm, sol::this_state s) { + lua_State *L = s; + luaL_Buffer buff; + s32 width, height; + vm.compute_snapshot_size(width, height); + int size = width * height * 4; + u32 *ptr = (u32 *)luaL_buffinitsize(L, &buff, size); + vm.pixels(ptr); + luaL_pushresultsize(&buff, size); + return sol::make_reference(L, sol::stack_reference(L, -1)); + }, "frameskip", sol::property(&video_manager::frameskip, &video_manager::set_frameskip), "throttled", sol::property(&video_manager::throttled, &video_manager::set_throttled), "throttle_rate", sol::property(&video_manager::throttle_rate, &video_manager::set_throttle_rate)); @@ -1920,7 +1938,7 @@ void lua_engine::initialize() * target:hidden() - is target hidden * target:is_ui_target() - is ui render target * target:index() - target index - * target:view_name(index) - current target layout view name + * target:view_name([opt] index) - current target layout view name * * target.max_update_rate - * target.view - current target layout view @@ -2012,8 +2030,9 @@ void lua_engine::initialize() * screen:height() - screen height * screen:width() - screen width * screen:orientation() - screen angle, flipx, flipy - * screen:refresh() - screen refresh rate - * screen:snapshot() - save snap shot + * screen:refresh() - screen refresh rate in Hz + * screen:refresh_attoseconds() - screen refresh rate in attoseconds + * screen:snapshot([opt] filename) - save snap shot * screen:type() - screen drawing type * screen:frame_number() - screen frame count * screen:name() - screen device full name @@ -2102,6 +2121,7 @@ void lua_engine::initialize() return std::tuple(rotation_angle, flags & ORIENTATION_FLIP_X, flags & ORIENTATION_FLIP_Y); }, "refresh", [](screen_device &sdev) { return ATTOSECONDS_TO_HZ(sdev.refresh_attoseconds()); }, + "refresh_attoseconds", [](screen_device &sdev) { return sdev.refresh_attoseconds(); }, "snapshot", [this](screen_device &sdev, sol::object filename) -> sol::object { emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); osd_file::error filerr; From 33c9f2f0725d0b4b7125eb4bc7260452d3819d69 Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 12 Jul 2019 23:05:54 +0300 Subject: [PATCH 2/2] fix for clang --- src/frontend/mame/luaengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index e761b79dae4..21a21006aac 100755 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -1850,12 +1850,12 @@ void lua_engine::initialize() "speed_factor", &video_manager::speed_factor, "speed_percent", &video_manager::speed_percent, "frame_update", &video_manager::frame_update, - "size", [this](video_manager &vm) { + "size", [](video_manager &vm) { s32 width, height; vm.compute_snapshot_size(width, height); return std::tuple(width, height); }, - "pixels", [this](video_manager &vm, sol::this_state s) { + "pixels", [](video_manager &vm, sol::this_state s) { lua_State *L = s; luaL_Buffer buff; s32 width, height;