diff options
Diffstat (limited to 'src/frontend/mame/luaengine.cpp')
-rw-r--r-- | src/frontend/mame/luaengine.cpp | 507 |
1 files changed, 217 insertions, 290 deletions
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); |