summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/luaengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/luaengine.cpp')
-rw-r--r--src/frontend/mame/luaengine.cpp507
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"] = &parameters_manager::add;
parameters_type["lookup"] = &parameters_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);