summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2020-11-25 19:18:26 +1100
committer Vas Crabb <vas@vastheman.com>2020-11-25 19:18:26 +1100
commitec8042864703f9ce6cc9b0cf528e6a8528104b89 (patch)
tree427556c7d86c7cab5f136aff7f0675adc443144b /src/frontend
parent8ea35743e40bd6dc01e50a0a21524db7b0ad203e (diff)
Fairly significant overhaul of Lua engine and some cleanup.
The things that were previously called device iterators are not iterators in the C++ sense of the word. This is confusing for newcomers. These have been renamed to be device enumerators. Several Lua methods and properties that previously returned tables now return lightweight wrappers for the underlying objects. This means creating them is a lot faster, but you can't modify them, and the performance characteristics of different operations varies. The render manager's target list uses 1-based indexing to be more like idiomatic Lua. It's now possible to create a device enumerator on any device, and then get subdevices (or sibling devices) using a relative tag. Much more render/layout functionality has been exposed to Lua. Layout scripts now have access to the layout file and can directly set the state of an item with no bindings, or register callbacks to obtain state. Some things that were previously methods are now read-only properties. Layout files are no longer required to supply a "name". This was problematic because the same layout file could be loaded for multiple instances of the same device, and each instance of the layout file should use the correct inputs (and in the future outputs) for the device instance it's associated with. This should also fix video output with MSVC builds by avoiding delegates that return things that don't fit in a register.
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/mame/audit.cpp4
-rw-r--r--src/frontend/mame/cheat.cpp2
-rw-r--r--src/frontend/mame/clifront.cpp20
-rw-r--r--src/frontend/mame/infoxml.cpp34
-rw-r--r--src/frontend/mame/luaengine.cpp485
-rw-r--r--src/frontend/mame/luaengine.h42
-rw-r--r--src/frontend/mame/luaengine.ipp95
-rw-r--r--src/frontend/mame/luaengine_render.cpp636
-rw-r--r--src/frontend/mame/mame.cpp20
-rw-r--r--src/frontend/mame/mameopts.cpp2
-rw-r--r--src/frontend/mame/media_ident.cpp2
-rw-r--r--src/frontend/mame/ui/datmenu.cpp3
-rw-r--r--src/frontend/mame/ui/devctrl.h20
-rw-r--r--src/frontend/mame/ui/devopt.cpp14
-rw-r--r--src/frontend/mame/ui/filemngr.cpp4
-rw-r--r--src/frontend/mame/ui/info.cpp12
-rw-r--r--src/frontend/mame/ui/info_pty.cpp2
-rw-r--r--src/frontend/mame/ui/inifile.cpp2
-rw-r--r--src/frontend/mame/ui/mainmenu.cpp12
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp4
-rw-r--r--src/frontend/mame/ui/selgame.cpp4
-rw-r--r--src/frontend/mame/ui/selsoft.cpp6
-rw-r--r--src/frontend/mame/ui/slotopt.cpp4
-rw-r--r--src/frontend/mame/ui/swlist.cpp3
-rw-r--r--src/frontend/mame/ui/ui.cpp16
-rw-r--r--src/frontend/mame/ui/viewgfx.cpp8
26 files changed, 1113 insertions, 343 deletions
diff --git a/src/frontend/mame/audit.cpp b/src/frontend/mame/audit.cpp
index 736d6f9bf2f..ce8e1368992 100644
--- a/src/frontend/mame/audit.cpp
+++ b/src/frontend/mame/audit.cpp
@@ -212,7 +212,7 @@ media_auditor::summary media_auditor::audit_media(const char *validation)
// iterate over devices and regions
std::vector<std::string> searchpath;
- for (device_t &device : device_iterator(m_enumerator.config()->root_device()))
+ for (device_t &device : device_enumerator(m_enumerator.config()->root_device()))
{
searchpath.clear();
@@ -400,7 +400,7 @@ media_auditor::summary media_auditor::audit_samples()
std::size_t found = 0;
// iterate over sample entries
- for (samples_device &device : samples_device_iterator(m_enumerator.config()->root_device()))
+ for (samples_device &device : samples_device_enumerator(m_enumerator.config()->root_device()))
{
// by default we just search using the driver name
std::string searchpath(m_enumerator.driver().name);
diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp
index 39846db0099..be5e9da9191 100644
--- a/src/frontend/mame/cheat.cpp
+++ b/src/frontend/mame/cheat.cpp
@@ -1146,7 +1146,7 @@ void cheat_manager::reload()
// load the cheat file, if it's a system that has a software list then try softlist_name/shortname.xml first,
// if it fails to load then try to load via crc32 - basename/crc32.xml ( eg. 01234567.xml )
- for (device_image_interface &image : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
{
if (image.exists())
{
diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp
index 978227bade0..1e8a59453c7 100644
--- a/src/frontend/mame/clifront.cpp
+++ b/src/frontend/mame/clifront.cpp
@@ -514,7 +514,7 @@ void cli_frontend::listcrc(const std::vector<std::string> &args)
args,
[] (device_t &root, char const *type, bool first)
{
- for (device_t const &device : device_iterator(root))
+ for (device_t const &device : device_enumerator(root))
{
for (tiny_rom_entry const *rom = device.rom_region(); rom && !ROMENTRY_ISEND(rom); ++rom)
{
@@ -548,7 +548,7 @@ void cli_frontend::listroms(const std::vector<std::string> &args)
// iterate through ROMs
bool hasroms = false;
- for (device_t const &device : device_iterator(root))
+ for (device_t const &device : device_enumerator(root))
{
for (const rom_entry *region = rom_first_region(device); region; region = rom_next_region(region))
{
@@ -618,7 +618,7 @@ void cli_frontend::listsamples(const std::vector<std::string> &args)
while (drivlist.next())
{
// see if we have samples
- samples_device_iterator iter(drivlist.config()->root_device());
+ samples_device_enumerator iter(drivlist.config()->root_device());
if (iter.count() == 0)
continue;
@@ -665,7 +665,7 @@ void cli_frontend::listdevices(const std::vector<std::string> &args)
// build a list of devices
std::vector<device_t *> device_list;
- for (device_t &device : device_iterator(drivlist.config()->root_device()))
+ for (device_t &device : device_enumerator(drivlist.config()->root_device()))
device_list.push_back(&device);
// sort them by tag
@@ -747,7 +747,7 @@ void cli_frontend::listslots(const std::vector<std::string> &args)
{
// iterate
bool first = true;
- for (const device_slot_interface &slot : slot_interface_iterator(drivlist.config()->root_device()))
+ for (const device_slot_interface &slot : slot_interface_enumerator(drivlist.config()->root_device()))
{
if (slot.fixed()) continue;
@@ -815,7 +815,7 @@ void cli_frontend::listmedia(const std::vector<std::string> &args)
{
// iterate
bool first = true;
- for (const device_image_interface &imagedev : image_interface_iterator(drivlist.config()->root_device()))
+ for (const device_image_interface &imagedev : image_interface_enumerator(drivlist.config()->root_device()))
{
if (!imagedev.user_loadable())
continue;
@@ -1215,7 +1215,7 @@ void cli_frontend::listsoftware(const std::vector<std::string> &args)
args,
[this, &list_map, &firstlist] (device_t &root, char const *type, bool first)
{
- for (software_list_device &swlistdev : software_list_device_iterator(root))
+ for (software_list_device &swlistdev : software_list_device_enumerator(root))
{
if (list_map.insert(swlistdev.list_name()).second)
{
@@ -1268,7 +1268,7 @@ void cli_frontend::verifysoftware(const std::vector<std::string> &args)
{
matched++;
- for (software_list_device &swlistdev : software_list_device_iterator(drivlist.config()->root_device()))
+ for (software_list_device &swlistdev : software_list_device_enumerator(drivlist.config()->root_device()))
{
if (swlistdev.is_original())
{
@@ -1330,7 +1330,7 @@ void cli_frontend::getsoftlist(const std::vector<std::string> &args)
std::vector<std::string>(),
[this, gamename, &list_map, &firstlist] (device_t &root, char const *type, bool first)
{
- for (software_list_device &swlistdev : software_list_device_iterator(root))
+ for (software_list_device &swlistdev : software_list_device_enumerator(root))
{
if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second)
{
@@ -1375,7 +1375,7 @@ void cli_frontend::verifysoftlist(const std::vector<std::string> &args)
while (drivlist.next())
{
- for (software_list_device &swlistdev : software_list_device_iterator(drivlist.config()->root_device()))
+ for (software_list_device &swlistdev : software_list_device_enumerator(drivlist.config()->root_device()))
{
if (core_strwildcmp(gamename, swlistdev.list_name().c_str()) == 0 && list_map.insert(swlistdev.list_name()).second)
{
diff --git a/src/frontend/mame/infoxml.cpp b/src/frontend/mame/infoxml.cpp
index 59b3a637aee..88d9e305b87 100644
--- a/src/frontend/mame/infoxml.cpp
+++ b/src/frontend/mame/infoxml.cpp
@@ -566,7 +566,7 @@ void output_footer(std::ostream &out)
void output_one(std::ostream &out, driver_enumerator &drivlist, const game_driver &driver, device_type_set *devtypes)
{
machine_config config(driver, drivlist.options());
- device_iterator iter(config.root_device());
+ device_enumerator iter(config.root_device());
// allocate input ports and build overall emulation status
ioport_list portlist;
@@ -685,7 +685,7 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi
{
bool has_speaker = false, has_input = false;
// check if the device adds speakers to the system
- sound_interface_iterator snditer(device);
+ sound_interface_enumerator snditer(device);
if (snditer.first() != nullptr)
has_speaker = true;
@@ -694,7 +694,7 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi
std::string errors;
device_t::feature_type overall_unemulated(device.type().unemulated_features());
device_t::feature_type overall_imperfect(device.type().imperfect_features());
- for (device_t &dev : device_iterator(device))
+ for (device_t &dev : device_enumerator(device))
{
portlist.append(dev, errors);
overall_unemulated |= dev.type().unemulated_features();
@@ -762,7 +762,7 @@ void output_devices(std::ostream &out, emu_options &lookup_options, device_type_
}
// notify this device and all its subdevices that they are now configured
- for (device_t &device : device_iterator(*dev))
+ for (device_t &device : device_enumerator(*dev))
if (!device.configured())
device.config_complete();
@@ -791,7 +791,7 @@ void output_devices(std::ostream &out, emu_options &lookup_options, device_type_
void output_device_refs(std::ostream &out, device_t &root)
{
- for (device_t &device : device_iterator(root))
+ for (device_t &device : device_enumerator(root))
if (&device != &root)
out << util::string_format("\t\t<device_ref name=\"%s\"/>\n", normalize_string(device.shortname()));
}
@@ -805,7 +805,7 @@ void output_device_refs(std::ostream &out, device_t &root)
void output_sampleof(std::ostream &out, device_t &device)
{
// iterate over sample devices
- for (samples_device &samples : samples_device_iterator(device))
+ for (samples_device &samples : samples_device_enumerator(device))
{
samples_iterator sampiter(samples);
if (sampiter.altbasename() != nullptr)
@@ -990,7 +990,7 @@ void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_drive
void output_sample(std::ostream &out, device_t &device)
{
// iterate over sample devices
- for (samples_device &samples : samples_device_iterator(device))
+ for (samples_device &samples : samples_device_enumerator(device))
{
samples_iterator iter(samples);
std::unordered_set<std::string> already_printed;
@@ -1015,7 +1015,7 @@ void output_sample(std::ostream &out, device_t &device)
void output_chips(std::ostream &out, device_t &device, const char *root_tag)
{
// iterate over executable devices
- for (device_execute_interface &exec : execute_interface_iterator(device))
+ for (device_execute_interface &exec : execute_interface_enumerator(device))
{
if (strcmp(exec.device().tag(), device.tag()))
{
@@ -1032,7 +1032,7 @@ void output_chips(std::ostream &out, device_t &device, const char *root_tag)
}
// iterate over sound devices
- for (device_sound_interface &sound : sound_interface_iterator(device))
+ for (device_sound_interface &sound : sound_interface_enumerator(device))
{
if (strcmp(sound.device().tag(), device.tag()) != 0 && sound.issound())
{
@@ -1059,7 +1059,7 @@ void output_chips(std::ostream &out, device_t &device, const char *root_tag)
void output_display(std::ostream &out, device_t &device, machine_flags::type const *flags, const char *root_tag)
{
// iterate over screens
- for (const screen_device &screendev : screen_device_iterator(device))
+ for (const screen_device &screendev : screen_device_enumerator(device))
{
if (strcmp(screendev.tag(), device.tag()))
{
@@ -1144,11 +1144,11 @@ void output_display(std::ostream &out, device_t &device, machine_flags::type con
void output_sound(std::ostream &out, device_t &device)
{
- speaker_device_iterator spkiter(device);
+ speaker_device_enumerator spkiter(device);
int speakers = spkiter.count();
// if we have no sound, zero m_output the speaker count
- sound_interface_iterator snditer(device);
+ sound_interface_enumerator snditer(device);
if (snditer.first() == nullptr)
speakers = 0;
@@ -1851,7 +1851,7 @@ void output_features(std::ostream &out, device_type type, device_t::feature_type
void output_images(std::ostream &out, device_t &device, const char *root_tag)
{
- for (const device_image_interface &imagedev : image_interface_iterator(device))
+ for (const device_image_interface &imagedev : image_interface_enumerator(device))
{
if (strcmp(imagedev.device().tag(), device.tag()))
{
@@ -1912,7 +1912,7 @@ void output_images(std::ostream &out, device_t &device, const char *root_tag)
void output_slots(std::ostream &out, machine_config &config, device_t &device, const char *root_tag, device_type_set *devtypes)
{
- for (device_slot_interface &slot : slot_interface_iterator(device))
+ for (device_slot_interface &slot : slot_interface_enumerator(device))
{
// shall we list fixed slots as non-configurable?
bool const listed(!slot.fixed() && strcmp(slot.device().tag(), device.tag()));
@@ -1936,7 +1936,7 @@ void output_slots(std::ostream &out, machine_config &config, device_t &device, c
dev->config_complete();
if (devtypes)
- for (device_t &subdevice : device_iterator(*dev)) devtypes->insert(&subdevice.type());
+ for (device_t &subdevice : device_enumerator(*dev)) devtypes->insert(&subdevice.type());
if (listed && option.second->selectable())
{
@@ -1965,7 +1965,7 @@ void output_slots(std::ostream &out, machine_config &config, device_t &device, c
void output_software_lists(std::ostream &out, device_t &root, const char *root_tag)
{
- for (const software_list_device &swlist : software_list_device_iterator(root))
+ for (const software_list_device &swlist : software_list_device_enumerator(root))
{
if (&static_cast<const device_t &>(swlist) == &root)
{
@@ -1992,7 +1992,7 @@ void output_software_lists(std::ostream &out, device_t &root, const char *root_t
void output_ramoptions(std::ostream &out, device_t &root)
{
- for (const ram_device &ram : ram_device_iterator(root, 1))
+ for (const ram_device &ram : ram_device_enumerator(root, 1))
{
if (!std::strcmp(ram.tag(), ":" RAM_TAG))
{
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 880ade2ab23..48ebc897899 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -37,24 +37,144 @@
//**************************************************************************
extern "C" {
- int luaopen_zlib(lua_State *L);
- int luaopen_lfs(lua_State *L);
- int luaopen_linenoise(lua_State *L);
- int luaopen_lsqlite3(lua_State *L);
-}
+
+int luaopen_zlib(lua_State *L);
+int luaopen_lfs(lua_State *L);
+int luaopen_linenoise(lua_State *L);
+int luaopen_lsqlite3(lua_State *L);
+
+} // extern "C"
+
+
+template <typename T>
+struct lua_engine::devenum
+{
+ devenum(device_t &d) : device(d), iter(d) { }
+
+ device_t &device;
+ T iter;
+ int count = -1;
+};
+
namespace sol
{
- sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking)
+
+sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking)
+{
+ return new sol::buffer(stack::get<int>(L, index), L);
+}
+
+int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value)
+{
+ delete value;
+ return 1;
+}
+
+template <typename T>
+struct usertype_container<lua_engine::devenum<T> > : lua_engine::immutable_container_helper<lua_engine::devenum<T>, T>
+{
+private:
+ using enumerator = lua_engine::devenum<T>;
+
+ template <bool Indexed>
+ static int next_pairs(lua_State *L)
{
- return new sol::buffer(stack::get<int>(L, index), L);
+ typename usertype_container::indexed_iterator &i(stack::unqualified_get<user<typename usertype_container::indexed_iterator> >(L, 1));
+ if (i.src.end() == i.it)
+ return stack::push(L, lua_nil);
+ int result;
+ if constexpr (Indexed)
+ result = stack::push(L, i.ix + 1);
+ else
+ result = stack::push(L, i.it->tag());
+ result += stack::push_reference(L, *i.it);
+ ++i;
+ return result;
}
- int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value)
+
+ template <bool Indexed>
+ static int start_pairs(lua_State *L)
{
- delete value;
- return 1;
+ enumerator &self(usertype_container::get_self(L));
+ stack::push(L, next_pairs<Indexed>);
+ stack::push<user<typename usertype_container::indexed_iterator> >(L, self.iter, self.iter.begin());
+ stack::push(L, lua_nil);
+ return 3;
+ }
+
+public:
+ static int at(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(L, 2));
+ auto const dev(self.iter.byindex(index - 1));
+ if (dev)
+ return stack::push_reference(L, *dev);
+ else
+ return stack::push(L, lua_nil);
}
-}
+
+ static int get(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ char const *const tag(stack::unqualified_get<char const *>(L));
+ device_t *const dev(self.device.subdevice(tag));
+ if (dev)
+ {
+ auto *const check(T(*dev, 0).first());
+ bool match;
+ if constexpr (std::is_base_of_v<device_t, decltype(*check)>)
+ match = check && (static_cast<device_t *>(check) == dev);
+ else if constexpr (std::is_base_of_v<device_interface, decltype(*check)>)
+ match = check && (&check->device() == dev);
+ else
+ match = check && (dynamic_cast<device_t *>(check) == dev);
+ if (match)
+ return stack::push_reference(L, *check);
+ }
+ return stack::push(L, lua_nil);
+ }
+
+ static int index_get(lua_State *L)
+ {
+ return get(L);
+ }
+
+ static int index_of(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ auto &dev(stack::unqualified_get<decltype(*self.iter.first())>(L, 2));
+ std::ptrdiff_t found(self.iter.indexof(dev));
+ if (0 > found)
+ return stack::push(L, lua_nil);
+ else
+ return stack::push(L, found + 1);
+ }
+
+ static int size(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ if (0 > self.count)
+ self.count = self.iter.count();
+ return stack::push(L, self.count);
+ }
+
+ static int empty(lua_State *L)
+ {
+ enumerator &self(usertype_container::get_self(L));
+ if (0 > self.count)
+ self.count = self.iter.count();
+ return stack::push(L, !self.count);
+ }
+
+ static int next(lua_State *L) { return stack::push(L, next_pairs<false>); }
+ static int pairs(lua_State *L) { return start_pairs<false>(L); }
+ static int ipairs(lua_State *L) { return start_pairs<true>(L); }
+};
+
+} // namespace sol
+
int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value)
{
@@ -461,17 +581,23 @@ void lua_engine::initialize()
* emu.print_error(str) - output to stderr at error level
* emu.print_info(str) - output to stderr at info level
* emu.print_debug(str) - output to stderr at debug level
+ *
+ * emu.device_enumerator(dev) - get device enumerator starting at arbitrary point in tree
+ * emu.screen_enumerator(dev) - get screen device enumerator starting at arbitrary point in tree
+ * emu.image_enumerator(dev) - get image interface enumerator starting at arbitrary point in tree
*/
sol::table emu = sol().create_named_table("emu");
emu["app_name"] = &emulator_info::get_appname_lower;
emu["app_version"] = &emulator_info::get_bare_build_version;
- emu["gamename"] = [this](){ return machine().system().type.fullname(); };
- emu["romname"] = [this](){ return machine().basename(); };
- emu["softname"] = [this]() { return machine().options().software_name(); };
- emu["keypost"] = [this](const char *keys){ machine().ioport().natkeyboard().post_utf8(keys); };
- emu["time"] = [this](){ return machine().time().as_double(); };
- emu["start"] = [this](const char *driver) {
+ emu["gamename"] = [this] () { return machine().system().type.fullname(); };
+ emu["romname"] = [this] () { return machine().basename(); };
+ emu["softname"] = [this] () { return machine().options().software_name(); };
+ emu["keypost"] = [this] (const char *keys) { machine().ioport().natkeyboard().post_utf8(keys); };
+ emu["time"] = [this] () { return machine().time().as_double(); };
+ emu["start"] =
+ [this](const char *driver)
+ {
int i = driver_list::find(driver);
if (i != -1)
{
@@ -480,69 +606,86 @@ void lua_engine::initialize()
}
return 1;
};
- emu["pause"] = [this](){ return machine().pause(); };
- emu["unpause"] = [this](){ return machine().resume(); };
- emu["step"] = [this]() {
+ emu["pause"] = [this] () { return machine().pause(); };
+ emu["unpause"] = [this] () { return machine().resume(); };
+ emu["step"] =
+ [this] ()
+ {
mame_machine_manager::instance()->ui().set_single_step(true);
machine().resume();
};
- emu["register_prestart"] = [this](sol::function func){ register_function(func, "LUA_ON_PRESTART"); };
- emu["register_start"] = [this](sol::function func){ register_function(func, "LUA_ON_START"); };
- emu["register_stop"] = [this](sol::function func){ register_function(func, "LUA_ON_STOP"); };
- emu["register_pause"] = [this](sol::function func){ register_function(func, "LUA_ON_PAUSE"); };
- emu["register_resume"] = [this](sol::function func){ register_function(func, "LUA_ON_RESUME"); };
- emu["register_frame"] = [this](sol::function func){ register_function(func, "LUA_ON_FRAME"); };
- 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_mandatory_file_manager_override"] = [this](sol::function func) { register_function(func, "LUA_ON_MANDATORY_FILE_MANAGER_OVERRIDE"); };
+ emu["register_prestart"] = [this] (sol::function func) { register_function(func, "LUA_ON_PRESTART"); };
+ emu["register_start"] = [this] (sol::function func) { register_function(func, "LUA_ON_START"); };
+ emu["register_stop"] = [this] (sol::function func) { register_function(func, "LUA_ON_STOP"); };
+ emu["register_pause"] = [this] (sol::function func) { register_function(func, "LUA_ON_PAUSE"); };
+ emu["register_resume"] = [this] (sol::function func) { register_function(func, "LUA_ON_RESUME"); };
+ emu["register_frame"] = [this] (sol::function func) { register_function(func, "LUA_ON_FRAME"); };
+ 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_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"] = [this](sol::function cb, sol::function pop, const std::string &name) {
+ emu["register_menu"] =
+ [this] (sol::function cb, sol::function pop, const std::string &name)
+ {
std::string cbfield = "menu_cb_" + name;
std::string popfield = "menu_pop_" + name;
sol().registry()[cbfield] = cb;
sol().registry()[popfield] = pop;
m_menu.push_back(name);
};
- emu["show_menu"] = [this](const char *name) {
+ emu["show_menu"] =
+ [this](const char *name)
+ {
mame_ui_manager &mui = mame_machine_manager::instance()->ui();
render_container &container = machine().render().ui_container();
ui::menu_plugin::show_menu(mui, container, (char *)name);
};
- emu["register_callback"] = [this](sol::function cb, const std::string &name) {
+ emu["register_callback"] =
+ [this] (sol::function cb, const std::string &name)
+ {
std::string field = "cb_" + name;
sol().registry()[field] = cb;
};
- emu["print_verbose"] = [](const char *str) { osd_printf_verbose("%s\n", str); };
- emu["print_error"] = [](const char *str) { osd_printf_error("%s\n", str); };
- 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 {
- int i = driver_list::find(driver);
- if(i == -1)
+ emu["print_verbose"] = [] (const char *str) { osd_printf_verbose("%s\n", str); };
+ emu["print_error"] = [] (const char *str) { osd_printf_error("%s\n", str); };
+ 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
+ {
+ 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));
};
- emu["wait"] = lua_CFunction([](lua_State *L) {
- lua_engine *engine = mame_machine_manager::instance()->lua();
- luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
- int ret = lua_pushthread(L);
- if(ret == 1)
- return luaL_error(L, "cannot wait from outside coroutine");
- int ref = luaL_ref(L, LUA_REGISTRYINDEX);
- engine->machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), engine), ref, nullptr);
- return lua_yield(L, 0);
- });
+ emu["wait"] = lua_CFunction(
+ [](lua_State *L)
+ {
+ lua_engine *engine = mame_machine_manager::instance()->lua();
+ luaL_argcheck(L, lua_isnumber(L, 1), 1, "waiting duration expected");
+ int ret = lua_pushthread(L);
+ if (ret == 1)
+ return luaL_error(L, "cannot wait from outside coroutine");
+ int ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ engine->machine().scheduler().timer_set(attotime::from_double(lua_tonumber(L, 1)), timer_expired_delegate(FUNC(lua_engine::resume), engine), ref, nullptr);
+ return lua_yield(L, 0);
+ });
emu["lang_translate"] = &lang_translate;
emu["pid"] = &osd_getpid;
- emu["subst_env"] = [](const std::string &str) {
+ emu["subst_env"] =
+ [] (const std::string &str)
+ {
std::string result;
osd_subst_env(result, str);
return result;
};
+ emu["device_enumerator"] = [] (device_t &d) { return devenum<device_enumerator>(d); };
+ emu["screen_enumerator"] = [] (device_t &d) { return devenum<screen_device_enumerator>(d); };
+ emu["image_enumerator"] = [] (device_t &d) { return devenum<image_interface_enumerator>(d); };
-/* emu_file library
+/* emu_file library
*
* emu.file([opt] searchpath, flags) - flags can be as in osdcore "OPEN_FLAG_*" or lua style
* with 'rwc' with addtional c for create *and truncate*
@@ -820,7 +963,7 @@ void lua_engine::initialize()
});
-/* core_options library
+/* core_options library
*
* manager:options()
* manager:machine():options()
@@ -957,12 +1100,14 @@ void lua_engine::initialize()
*/
auto machine_type = sol().registry().new_usertype<running_machine>("machine", "new", sol::no_constructor);
- machine_type.set("exit", &running_machine::schedule_exit);
- machine_type.set("hard_reset", &running_machine::schedule_hard_reset);
- machine_type.set("soft_reset", &running_machine::schedule_soft_reset);
- machine_type.set("save", &running_machine::schedule_save);
- machine_type.set("load", &running_machine::schedule_load);
- machine_type.set("buffer_save", [](running_machine &m, sol::this_state s) {
+ 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["buffer_save"] =
+ [] (running_machine &m, sol::this_state s)
+ {
lua_State *L = s;
luaL_Buffer buff;
int size = ram_state::get_size(m.save());
@@ -975,8 +1120,10 @@ void lua_engine::initialize()
}
luaL_error(L, "State save error.");
return sol::make_reference(L, nullptr);
- });
- machine_type.set("buffer_load", [](running_machine &m, sol::this_state s, std::string str) {
+ };
+ machine_type["buffer_load"] =
+ [] (running_machine &m, sol::this_state s, std::string str)
+ {
lua_State *L = s;
save_error error = m.save().read_buffer((u8 *)str.data(), str.size());
if (error == STATERR_NONE)
@@ -986,65 +1133,36 @@ void lua_engine::initialize()
luaL_error(L,"State load error.");
return false;
}
- });
- machine_type.set("system", &running_machine::system);
- machine_type.set("video", &running_machine::video);
- machine_type.set("sound", &running_machine::sound);
- machine_type.set("render", &running_machine::render);
- machine_type.set("ioport", &running_machine::ioport);
- machine_type.set("parameters", &running_machine::parameters);
- machine_type.set("memory", &running_machine::memory);
- machine_type.set("options", [](running_machine &m) { return static_cast<core_options *>(&m.options()); });
- machine_type.set("outputs", &running_machine::output);
- machine_type.set("input", &running_machine::input);
- machine_type.set("uiinput", &running_machine::ui_input);
- machine_type.set("debugger", [this](running_machine &m) -> sol::object {
+ };
+ 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 &m) { return static_cast<core_options *>(&m.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
+ {
if(!(m.debug_flags & DEBUG_FLAG_ENABLED))
return sol::make_object(sol(), sol::lua_nil);
return sol::make_object(sol(), &m.debugger());
- });
- machine_type.set("paused", sol::property(&running_machine::paused));
- machine_type.set("samplerate", sol::property(&running_machine::sample_rate));
- machine_type.set("exit_pending", sol::property(&running_machine::exit_pending));
- machine_type.set("hard_reset_pending", sol::property(&running_machine::hard_reset_pending));
- machine_type.set("devices", sol::property([this](running_machine &m) {
- std::function<void(device_t &, sol::table)> tree;
- sol::table table = sol().create_table();
- tree = [&tree](device_t &root, sol::table table) {
- for(device_t &dev : root.subdevices())
- {
- if(dev.configured() && dev.started())
- {
- table[dev.tag()] = &dev;
- tree(dev, table);
- }
- }
- };
- tree(m.root_device(), table);
- return table;
- }));
- machine_type.set("screens", sol::property([this](running_machine &r) {
- sol::table table = sol().create_table();
- for (screen_device &sc : screen_device_iterator(r.root_device()))
- {
- if (sc.configured() && sc.started() && sc.type())
- table[sc.tag()] = &sc;
- }
- return table;
- }));
- machine_type.set("images", sol::property([this](running_machine &r) {
- sol::table image_table = sol().create_table();
- for(device_image_interface &image : image_interface_iterator(r.root_device()))
- {
- image_table[image.brief_instance_name()] = &image;
- image_table[image.instance_name()] = &image;
- }
- return image_table;
- }));
- machine_type.set("popmessage", sol::overload(
+ };
+ 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);
+ machine_type["hard_reset_pending"] = sol::property(&running_machine::hard_reset_pending);
+ machine_type["devices"] = sol::property([] (running_machine &m) { return devenum<device_enumerator>(m.root_device()); });
+ machine_type["screens"] = sol::property([] (running_machine &m) { return devenum<screen_device_enumerator>(m.root_device()); });
+ machine_type["images"] = sol::property([] (running_machine &m) { return devenum<image_interface_enumerator>(m.root_device()); });
+ machine_type["popmessage"] = sol::overload(
[](running_machine &m, const char *str) { m.popmessage("%s", str); },
- [](running_machine &m) { m.popmessage(); }));
- machine_type.set("logerror", [](running_machine &m, const char *str) { m.logerror("[luaengine] %s\n", str); } );
+ [](running_machine &m) { m.popmessage(); });
+ machine_type["logerror"] = [] (running_machine &m, const char *str) { m.logerror("[luaengine] %s\n", str); };
/* game_driver library
@@ -1270,6 +1388,8 @@ void lua_engine::initialize()
* device:owner() - device parent tag
* device:debug() - debug interface, cpus only
*
+ * device.configured - whether configuration is complete
+ * device.started - whether the device has been started
* device.spaces[] - device address spaces table (k=name, v=addr_space)
* device.state[] - device state entries table (k=name, v=device_state_entry)
* device.items[] - device save state items table (k=name, v=index)
@@ -1277,65 +1397,77 @@ void lua_engine::initialize()
*/
auto device_type = sol().registry().new_usertype<device_t>("device", "new", sol::no_constructor);
- device_type.set("name", &device_t::name);
- device_type.set("shortname", &device_t::shortname);
- device_type.set("tag", &device_t::tag);
- device_type.set("owner", &device_t::owner);
- device_type.set("debug", [this](device_t &dev) -> sol::object {
- if(!(dev.machine().debug_flags & DEBUG_FLAG_ENABLED) || !dynamic_cast<cpu_device *>(&dev)) // debugger not enabled or not cpu
+ device_type["name"] = &device_t::name;
+ device_type["shortname"] = &device_t::shortname;
+ device_type["tag"] = &device_t::tag;
+ device_type["owner"] = &device_t::owner;
+ device_type["debug"] =
+ [this] (device_t &dev) -> 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());
- });
- device_type.set("spaces", sol::property([this](device_t &dev) {
- device_memory_interface *memdev = dynamic_cast<device_memory_interface *>(&dev);
- sol::table sp_table = sol().create_table();
- if(!memdev)
+ };
+ device_type["configured"] = sol::property(&device_t::configured);
+ device_type["started"] = sol::property(&device_t::started);
+ device_type["spaces"] = sol::property(
+ [this] (device_t &dev)
+ {
+ device_memory_interface *memdev = dynamic_cast<device_memory_interface *>(&dev);
+ sol::table sp_table = sol().create_table();
+ if(!memdev)
+ return sp_table;
+ for(int sp = 0; sp < memdev->max_space_count(); ++sp)
+ {
+ if(memdev->has_space(sp))
+ sp_table[memdev->space(sp).name()] = addr_space(memdev->space(sp), *memdev);
+ }
return sp_table;
- for(int sp = 0; sp < memdev->max_space_count(); ++sp)
+ });
+ device_type["state"] = sol::property(
+ [this] (device_t &dev)
{
- if(memdev->has_space(sp))
- sp_table[memdev->space(sp).name()] = addr_space(memdev->space(sp), *memdev);
- }
- return sp_table;
- }));
- device_type.set("state", sol::property([this](device_t &dev) {
- sol::table st_table = sol().create_table();
- if(!dynamic_cast<device_state_interface *>(&dev))
+ sol::table st_table = sol().create_table();
+ if(!dynamic_cast<device_state_interface *>(&dev))
+ return st_table;
+ // XXX: refrain from exporting non-visible entries?
+ for(auto &s : dev.state().state_entries())
+ st_table[s->symbol()] = s.get();
return st_table;
- // XXX: refrain from exporting non-visible entries?
- for(auto &s : dev.state().state_entries())
- st_table[s->symbol()] = s.get();
- return st_table;
- }));
- device_type.set("items", sol::property([this](device_t &dev) {
- sol::table table = sol().create_table();
- std::string tag = dev.tag();
- // 10000 is enough?
- for(int i = 0; i < 10000; i++)
+ });
+ device_type["items"] = sol::property(
+ [this] (device_t &dev)
{
- std::string name;
- const char *item;
- void *base;
- uint32_t size, valcount, blockcount, stride;
- item = dev.machine().save().indexed_item(i, base, size, valcount, blockcount, stride);
- if(!item)
- break;
- name = &(strchr(item, '/')[1]);
- if(name.substr(0, name.find('/')) == tag)
+ sol::table table = sol().create_table();
+ std::string tag = dev.tag();
+ // 10000 is enough?
+ for(int i = 0; i < 10000; i++)
{
- name = name.substr(name.find('/') + 1, std::string::npos);
- table[name] = i;
+ std::string name;
+ const char *item;
+ void *base;
+ uint32_t size, valcount, blockcount, stride;
+ item = dev.machine().save().indexed_item(i, base, size, valcount, blockcount, stride);
+ if(!item)
+ break;
+ name = &(strchr(item, '/')[1]);
+ if(name.substr(0, name.find('/')) == tag)
+ {
+ name = name.substr(name.find('/') + 1, std::string::npos);
+ table[name] = i;
+ }
}
- }
- return table;
- }));
- device_type.set("roms", sol::property([this](device_t &dev) {
- sol::table table = sol().create_table();
- for(auto rom : dev.rom_region_vector())
- if(!rom.name().empty())
- table[rom.name()] = rom;
- return table;
- }));
+ return table;
+ });
+ device_type["roms"] = sol::property(
+ [this] (device_t &dev)
+ {
+ sol::table table = sol().create_table();
+ for(auto rom : dev.rom_region_vector())
+ if(!rom.name().empty())
+ table[rom.name()] = rom;
+ return table;
+ });
/* parameters_manager library
@@ -1346,9 +1478,9 @@ void lua_engine::initialize()
* parameters:lookup(tag) - get val for tag
*/
- sol().registry().new_usertype<parameters_manager>("parameters", "new", sol::no_constructor,
- "add", &parameters_manager::add,
- "lookup", &parameters_manager::lookup);
+ auto parameters_type = sol().registry().new_usertype<parameters_manager>("parameters", "new", sol::no_constructor);
+ parameters_type["add"] = &parameters_manager::add;
+ parameters_type["lookup"] = &parameters_manager::lookup;
/* video_manager library
@@ -1881,16 +2013,3 @@ void lua_engine::load_string(const char *value)
{
run(sol().load(value));
}
-
-//-------------------------------------------------
-// invoke - invokes a function, wrapping profiler
-//-------------------------------------------------
-
-template<typename TFunc, typename... TArgs>
-sol::protected_function_result lua_engine::invoke(TFunc &&func, TArgs&&... args)
-{
- g_profiler.start(PROFILER_LUA);
- sol::protected_function_result result = func(std::forward<TArgs>(args)...);
- g_profiler.stop();
- return result;
-}
diff --git a/src/frontend/mame/luaengine.h b/src/frontend/mame/luaengine.h
index ed871d53287..3053de34b7d 100644
--- a/src/frontend/mame/luaengine.h
+++ b/src/frontend/mame/luaengine.h
@@ -33,6 +33,10 @@ struct lua_State;
class lua_engine
{
public:
+ // helper structures
+ template <typename T> struct devenum;
+ template <typename T, typename C, typename I = typename C::iterator> struct immutable_container_helper;
+
// construction/destruction
lua_engine();
~lua_engine();
@@ -55,12 +59,12 @@ public:
bool on_missing_mandatory_image(const std::string &instance_name);
void on_machine_before_load_settings();
- template<typename T, typename U>
- bool call_plugin(const std::string &name, const T in, U &out)
+ template <typename T, typename U>
+ bool call_plugin(const std::string &name, T &&in, U &out)
{
bool ret = false;
- sol::object outobj = call_plugin(name, sol::make_object(sol(), in));
- if(outobj.is<U>())
+ sol::object outobj = call_plugin(name, sol::make_object(sol(), std::forward<T>(in)));
+ if (outobj.is<U>())
{
out = outobj.as<U>();
ret = true;
@@ -68,16 +72,16 @@ public:
return ret;
}
- template<typename T, typename U>
- bool call_plugin(const std::string &name, const T in, std::vector<U> &out)
+ template <typename T, typename U>
+ bool call_plugin(const std::string &name, T &&in, std::vector<U> &out)
{
bool ret = false;
- sol::object outobj = call_plugin(name, sol::make_object(sol(), in));
- if(outobj.is<sol::table>())
+ sol::object outobj = call_plugin(name, sol::make_object(sol(), std::forward<T>(in)));
+ if (outobj.is<sol::table>())
{
- for(auto &entry : outobj.as<sol::table>())
+ for (auto &entry : outobj.as<sol::table>())
{
- if(entry.second.template is<U>())
+ if (entry.second.template is<U>())
{
out.push_back(entry.second.template as<U>());
ret = true;
@@ -88,26 +92,26 @@ public:
}
// this can also check if a returned table contains type T
- template<typename T, typename U>
- bool call_plugin_check(const std::string &name, const U in, bool table = false)
+ template <typename T, typename U>
+ bool call_plugin_check(const std::string &name, U &&in, bool table = false)
{
bool ret = false;
- sol::object outobj = call_plugin(name, sol::make_object(sol(), in));
- if(outobj.is<T>() && !table)
+ sol::object outobj = call_plugin(name, sol::make_object(sol(), std::forward<U>(in)));
+ if (outobj.is<T>() && !table)
ret = true;
- else if(outobj.is<sol::table>() && table)
+ else if (outobj.is<sol::table>() && table)
{
// check just one entry, checking the whole thing shouldn't be necessary as this only supports homogeneous tables
- if(outobj.as<sol::table>().begin().operator*().second.template is<T>())
+ if (outobj.as<sol::table>().begin().operator*().second.template is<T>())
ret = true;
}
return ret;
}
- template<typename T>
- void call_plugin_set(const std::string &name, const T in)
+ template <typename T>
+ void call_plugin_set(const std::string &name, T &&in)
{
- call_plugin(name, sol::make_object(sol(), in));
+ call_plugin(name, sol::make_object(sol(), std::forward<T>(in)));
}
sol::state_view &sol() const { return *m_sol_state; }
diff --git a/src/frontend/mame/luaengine.ipp b/src/frontend/mame/luaengine.ipp
index cb6824dd262..78652d557e6 100644
--- a/src/frontend/mame/luaengine.ipp
+++ b/src/frontend/mame/luaengine.ipp
@@ -59,21 +59,98 @@ private:
// don't convert core_optons to a table directly
-template<> struct is_container<core_options> : std::false_type { };
+template <> struct is_container<core_options> : std::false_type { };
+// buffer customisation
sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking);
int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value);
+// lua_engine::devenum customisation
+template <typename T> struct is_container<lua_engine::devenum<T> > : std::true_type { };
+template <typename T> struct usertype_container<lua_engine::devenum<T> >;
+
} // namespace sol
+// osd_file::error customisation
int sol_lua_push(sol::types<osd_file::error>, lua_State *L, osd_file::error &&value);
template <typename Handler>
bool sol_lua_check(sol::types<osd_file::error>, lua_State *L, int index, Handler &&handler, sol::stack::record &tracking);
+// map_handler_type customisation
int sol_lua_push(sol::types<map_handler_type>, lua_State *L, map_handler_type &&value);
+template <typename T, typename C, typename I = typename C::iterator>
+struct lua_engine::immutable_container_helper
+{
+protected:
+ using iterator = I;
+
+ static T &get_self(lua_State *L)
+ {
+ auto p(sol::stack::unqualified_check_get<T *>(L, 1));
+ if (!p)
+ luaL_error(L, "sol: 'self' is not of type '%s' (pass 'self' as first argument with ':' or call on proper type)", sol::detail::demangle<T>().c_str());
+ if (!p.value())
+ luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument with ':' or call on a '%s' type", sol::detail::demangle<T>().c_str());
+ return *p.value();
+ }
+
+ struct indexed_iterator
+ {
+ indexed_iterator(C &s, iterator i) : src(s), it(i), ix(0U) { }
+
+ C &src;
+ iterator it;
+ std::size_t ix;
+
+ indexed_iterator &operator++()
+ {
+ ++it;
+ ++ix;
+ return *this;
+ }
+ };
+
+public:
+ static int set(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'set(key, value)' on type '%s': container is not modifiable", sol::detail::demangle<T>().c_str());
+ }
+
+ static int index_set(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'container[key] = value' on type '%s': container is not modifiable", sol::detail::demangle<T>().c_str());
+ }
+
+ static int add(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'add' on type '%s': container is not modifiable", sol::detail::demangle<T>().c_str());
+ }
+
+ static int insert(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'insert' on type '%s': container is not modifiable", sol::detail::demangle<T>().c_str());
+ }
+
+ static int find(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'find' on type '%s': no supported comparison operator for the value type", sol::detail::demangle<T>().c_str());
+ }
+
+ static int clear(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'clear' on type '%s': container is not modifiable", sol::detail::demangle<T>().c_str());
+ }
+
+ static int erase(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'erase' on type '%s': container is not modifiable", sol::detail::demangle<T>().c_str());
+ }
+};
+
+
struct lua_engine::addr_space
{
addr_space(address_space &s, device_memory_interface &d) : space(s), dev(d) { }
@@ -90,7 +167,7 @@ struct lua_engine::addr_space
};
-template<typename T, size_t SIZE>
+template <typename T, size_t SIZE>
class lua_engine::enum_parser
{
public:
@@ -121,4 +198,18 @@ private:
std::array<std::pair<const char *, T>, SIZE> m_map;
};
+
+//-------------------------------------------------
+// invoke - invokes a function, wrapping profiler
+//-------------------------------------------------
+
+template <typename TFunc, typename... TArgs>
+inline sol::protected_function_result lua_engine::invoke(TFunc &&func, TArgs &&... args)
+{
+ g_profiler.start(PROFILER_LUA);
+ sol::protected_function_result result = func(std::forward<TArgs>(args)...);
+ g_profiler.stop();
+ return result;
+}
+
#endif // MAME_FRONTEND_MAME_LUAENGINE_IPP
diff --git a/src/frontend/mame/luaengine_render.cpp b/src/frontend/mame/luaengine_render.cpp
index 01fdbe9add9..94945ad0bf1 100644
--- a/src/frontend/mame/luaengine_render.cpp
+++ b/src/frontend/mame/luaengine_render.cpp
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
-// copyright-holders:Miodrag Milanovic,Luca Bruno
+// copyright-holders:Vas Crabb
/***************************************************************************
- luaengine_input.cpp
+ luaengine_render.cpp
Controls execution of the core MAME system.
@@ -13,6 +13,304 @@
#include "render.h"
+#include <iterator>
+
+
+namespace {
+
+struct layout_file_views
+{
+ layout_file_views(layout_file &f) : file(f) { }
+
+ layout_file &file;
+};
+
+
+struct layout_view_items
+{
+ layout_view_items(layout_view &v) : view(v) { }
+
+ layout_view &view;
+};
+
+
+struct render_manager_targets
+{
+ render_manager_targets(render_manager &m) : targets(m.targets()) { }
+
+ simple_list<render_target> const &targets;
+};
+
+} // anonymous namespace
+
+namespace sol {
+
+template <> struct is_container<layout_file_views> : std::true_type { };
+template <> struct is_container<layout_view_items> : std::true_type { };
+template <> struct is_container<render_manager_targets> : std::true_type { };
+
+
+template <>
+struct usertype_container<layout_file_views> : lua_engine::immutable_container_helper<layout_file_views, layout_file::view_list>
+{
+private:
+ using view_list = layout_file::view_list;
+
+ template <bool Indexed>
+ static int next_pairs(lua_State *L)
+ {
+ indexed_iterator &i(stack::unqualified_get<user<indexed_iterator> >(L, 1));
+ if (i.src.end() == i.it)
+ return stack::push(L, lua_nil);
+ int result;
+ if constexpr (Indexed)
+ result = stack::push(L, i.ix + 1);
+ else
+ result = stack::push_reference(L, i.it->unqualified_name());
+ result += stack::push_reference(L, *i.it);
+ ++i;
+ return result;
+ }
+
+ template <bool Indexed>
+ static int start_pairs(lua_State *L)
+ {
+ layout_file_views &self(get_self(L));
+ stack::push(L, next_pairs<Indexed>);
+ stack::push<user<indexed_iterator> >(L, self.file.views(), self.file.views().begin());
+ stack::push(L, lua_nil);
+ return 3;
+ }
+
+public:
+ static int at(lua_State *L)
+ {
+ layout_file_views &self(get_self(L));
+ std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(L, 2));
+ if ((0 >= index) || (self.file.views().size() < index))
+ return stack::push(L, lua_nil);
+ else
+ return stack::push_reference(L, *std::next(self.file.views().begin(), index - 1));
+ }
+
+ static int get(lua_State *L)
+ {
+ layout_file_views &self(get_self(L));
+ char const *const name(stack::unqualified_get<char const *>(L));
+ auto const found(std::find_if(
+ self.file.views().begin(),
+ self.file.views().end(),
+ [&name] (layout_view &v) { return v.unqualified_name() == name; }));
+ if (self.file.views().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);
+ }
+
+ static int index_of(lua_State *L)
+ {
+ layout_file_views &self(get_self(L));
+ layout_view &view(stack::unqualified_get<layout_view>(L, 2));
+ auto it(self.file.views().begin());
+ std::ptrdiff_t ix(0);
+ while ((self.file.views().end() != it) && (&view != &*it))
+ {
+ ++it;
+ ++ix;
+ }
+ if (self.file.views().end() == it)
+ return stack::push(L, lua_nil);
+ else
+ return stack::push(L, ix + 1);
+ }
+
+ static int size(lua_State *L)
+ {
+ layout_file_views &self(get_self(L));
+ return stack::push(L, self.file.views().size());
+ }
+
+ static int empty(lua_State *L)
+ {
+ layout_file_views &self(get_self(L));
+ return stack::push(L, self.file.views().empty());
+ }
+
+ static int next(lua_State *L) { return stack::push(L, next_pairs<false>); }
+ static int pairs(lua_State *L) { return start_pairs<false>(L); }
+ static int ipairs(lua_State *L) { return start_pairs<true>(L); }
+};
+
+
+template <>
+struct usertype_container<layout_view_items> : lua_engine::immutable_container_helper<layout_view_items, layout_view::item_list>
+{
+private:
+ using item_list = layout_view::item_list;
+
+ static int next_pairs(lua_State *L)
+ {
+ indexed_iterator &i(stack::unqualified_get<user<indexed_iterator> >(L, 1));
+ if (i.src.end() == i.it)
+ return stack::push(L, lua_nil);
+ int result;
+ result = stack::push(L, i.ix + 1);
+ result += stack::push_reference(L, *i.it);
+ ++i.it;
+ ++i.ix;
+ return result;
+ }
+
+public:
+ static int at(lua_State *L)
+ {
+ layout_view_items &self(get_self(L));
+ std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(L, 2));
+ if ((0 >= index) || (self.view.items().size() < index))
+ return stack::push(L, lua_nil);
+ else
+ return stack::push_reference(L, *std::next(self.view.items().begin(), index - 1));
+ }
+
+ static int get(lua_State *L)
+ {
+ layout_view_items &self(get_self(L));
+ char const *const id(stack::unqualified_get<char const *>(L));
+ layout_view::item *const item(self.view.get_item(id));
+ if (item)
+ return stack::push_reference(L, *item);
+ else
+ return stack::push(L, lua_nil);
+ }
+
+ static int index_get(lua_State *L)
+ {
+ return get(L);
+ }
+
+ static int index_of(lua_State *L)
+ {
+ layout_view_items &self(get_self(L));
+ layout_view::item &item(stack::unqualified_get<layout_view::item>(L, 2));
+ auto it(self.view.items().begin());
+ std::ptrdiff_t ix(0);
+ while ((self.view.items().end() != it) && (&item != &*it))
+ {
+ ++it;
+ ++ix;
+ }
+ if (self.view.items().end() == it)
+ return stack::push(L, lua_nil);
+ else
+ return stack::push(L, ix + 1);
+ }
+
+ static int size(lua_State *L)
+ {
+ layout_view_items &self(get_self(L));
+ return stack::push(L, self.view.items().size());
+ }
+
+ static int empty(lua_State *L)
+ {
+ layout_view_items &self(get_self(L));
+ return stack::push(L, self.view.items().empty());
+ }
+
+ static int next(lua_State *L) { return stack::push(L, next_pairs); }
+
+ static int pairs(lua_State *L)
+ {
+ return luaL_error(L, "sol: cannot call 'pairs' on type '%s': not iterable by ID", sol::detail::demangle<layout_view_items>().c_str());
+ }
+
+ static int ipairs(lua_State *L)
+ {
+ layout_view_items &self(get_self(L));
+ stack::push(L, next_pairs);
+ stack::push<user<indexed_iterator> >(L, self.view.items(), self.view.items().begin());
+ stack::push(L, lua_nil);
+ return 3;
+ }
+};
+
+
+template <>
+struct usertype_container<render_manager_targets> : lua_engine::immutable_container_helper<render_manager_targets, simple_list<render_target> const, simple_list<render_target>::auto_iterator>
+{
+private:
+ using target_list = simple_list<render_target>;
+
+ static int next_pairs(lua_State *L)
+ {
+ indexed_iterator &i(stack::unqualified_get<user<indexed_iterator> >(L, 1));
+ if (i.src.end() == i.it)
+ return stack::push(L, lua_nil);
+ int result;
+ result = stack::push(L, i.ix + 1);
+ result += stack::push_reference(L, *i.it);
+ ++i.it;
+ ++i.ix;
+ return result;
+ }
+
+public:
+ static int at(lua_State *L)
+ {
+ render_manager_targets &self(get_self(L));
+ std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(L, 2));
+ if ((0 >= index) || (self.targets.count() < index))
+ return stack::push(L, lua_nil);
+ else
+ return stack::push_reference(L, *self.targets.find(index - 1));
+ }
+
+ static int get(lua_State *L) { return at(L); }
+ static int index_get(lua_State *L) { return at(L); }
+
+ static int index_of(lua_State *L)
+ {
+ render_manager_targets &self(get_self(L));
+ render_target &target(stack::unqualified_get<render_target>(L, 2));
+ int const found(self.targets.indexof(target));
+ if (0 > found)
+ return stack::push(L, lua_nil);
+ else
+ return stack::push(L, found + 1);
+ }
+
+ static int size(lua_State *L)
+ {
+ render_manager_targets &self(get_self(L));
+ return stack::push(L, self.targets.count());
+ }
+
+ static int empty(lua_State *L)
+ {
+ render_manager_targets &self(get_self(L));
+ return stack::push(L, self.targets.empty());
+ }
+
+ static int next(lua_State *L) { return stack::push(L, next_pairs); }
+ static int pairs(lua_State *L) { return ipairs(L); }
+
+ static int ipairs(lua_State *L)
+ {
+ render_manager_targets &self(get_self(L));
+ stack::push(L, next_pairs);
+ stack::push<user<indexed_iterator> >(L, self.targets, self.targets.begin());
+ stack::push(L, lua_nil);
+ return 3;
+ }
+};
+
+} // namespace sol
+
//-------------------------------------------------
// initialize_render - register render user types
@@ -21,12 +319,271 @@
void lua_engine::initialize_render()
{
+/* render_bounds library
+ *
+ * bounds:includes(x, y) - returns true if point is within bounds
+ * bounds:set_xy(left, top, right, bottom) - set bounds
+ * bounds:set_wh(left, top, width, height) - set bounds
+ *
+ * bounds.x0 - leftmost X coordinate
+ * bounds.y0 - topmost Y coordinate
+ * bounds.x1 - rightmost X coordinate
+ * bounds.y1 - bottommost Y coordinate
+ * bounds.width - get/set width
+ * bounds.height - get/set height
+ * bounds.aspect - read-only aspect ratio width:height
+ */
+ auto bounds_type = sol().registry().new_usertype<render_bounds>("bounds", sol::call_constructor, sol::initializers(
+ [] (render_bounds &b) { new (&b) render_bounds{ 0.0F, 0.0F, 1.0F, 1.0F }; },
+ [] (render_bounds &b, float x0, float y0, float x1, float y1) { new (&b) render_bounds{ x0, y0, x1, y1 }; }));
+ bounds_type["includes"] = &render_bounds::includes;
+ bounds_type["set_xy"] = &render_bounds::includes;
+ bounds_type["set_wh"] = &render_bounds::includes;
+ bounds_type["x0"] = &render_bounds::x0;
+ bounds_type["y0"] = &render_bounds::y0;
+ bounds_type["x1"] = &render_bounds::x1;
+ bounds_type["y1"] = &render_bounds::y1;
+ bounds_type["width"] = sol::property(&render_bounds::width, [] (render_bounds &b, float w) { b.x1 = b.x0 + w; });
+ bounds_type["height"] = sol::property(&render_bounds::height, [] (render_bounds &b, float h) { b.y1 = b.y0 + h; });
+ bounds_type["aspect"] = sol::property(&render_bounds::aspect);
+
+
+/* render_color library
+ *
+ * set(a, r, g, b) - set color
+ *
+ * color.a - alpha channel
+ * color.r - red channel
+ * color.g - green channel
+ * color.b - blue channel
+ */
+ auto color_type = sol().registry().new_usertype<render_color>("color", sol::call_constructor, sol::initializers(
+ [] (render_color &c) { new (&c) render_color{ 1.0F, 1.0F, 1.0F, 1.0F }; },
+ [] (render_color &c, float a, float r, float g, float b) { new (&c) render_color{ a, r, g, b }; }));
+ color_type["set"] = &render_color::set;
+ color_type["a"] = &render_color::a;
+ color_type["r"] = &render_color::r;
+ color_type["g"] = &render_color::g;
+ color_type["b"] = &render_color::b;
+
+
+/* layout_view library
+ *
+ * manager:machine():render().targets[target_index]:current_view()
+ *
+ * view:has_screen(screen) - returns whether a given screen is present in the view (including hidden screens)
+ *
+ * view.items - get the items in the view (including hidden items)
+ * view.name - display name for the view
+ * view.unqualified_name - name of the view as specified in the layout file
+ * view.visible_screen_count - number of screens items currently enabled
+ * view.effective_aspect - effective aspect ratio in current configuration
+ * view.bounds - effective bounds in current configuration
+ * view.has_art - true if the view has non-screen items
+ */
+
+ auto layout_view_type = sol().registry().new_usertype<layout_view>("layout_view", sol::no_constructor);
+ layout_view_type["has_screen"] = &layout_view::has_screen;
+ layout_view_type["items"] = sol::property([] (layout_view &v) { return layout_view_items(v); });
+ layout_view_type["name"] = sol::property(&layout_view::name);
+ layout_view_type["unqualified_name"] = sol::property(&layout_view::unqualified_name);
+ layout_view_type["visible_screen_count"] = sol::property(&layout_view::visible_screen_count);
+ layout_view_type["effective_aspect"] = sol::property(&layout_view::effective_aspect);
+ layout_view_type["bounds"] = sol::property(&layout_view::bounds);
+ layout_view_type["has_art"] = sol::property(&layout_view::has_art);
+
+
+/* layout_view::item library
+ *
+ * item:set_state(state) - set state value used in absence of bindings
+ * item.set_element_state_callback(cb) - set callback to obtain element state
+ * item.set_animation_state_callback(cb) - set callback to obtain animation state
+ * item.set_bounds_callback(cb) - set callback to obtain item bounds
+ * item.set_color_callback(cb) - set callback to obtain item color
+ *
+ * item.id - get optional item identifier
+ * item.bounds_animated - true if bounds depend on state
+ * item.color_animated - true if color depends on state
+ * item.bounds - get bounds for current state
+ * item.color - get color for current state
+ * item.blend_mode - get blend mode or -1
+ * item.orientation - get item orientation
+ * item.element_state - get effective element state
+ * item.animation_state - get effective animation state
+ */
+
+ auto layout_view_item_type = sol().registry().new_usertype<layout_view::item>("layout_item", sol::no_constructor);
+ layout_view_item_type["set_state"] = &layout_view::item::set_state;
+ layout_view_item_type["set_element_state_callback"] =
+ [this] (layout_view::item &i, sol::object cb)
+ {
+ if (cb == sol::lua_nil)
+ {
+ i.set_element_state_callback(layout_view::item::state_delegate());
+ }
+ else if (cb.is<sol::protected_function>())
+ {
+ i.set_element_state_callback(layout_view::item::state_delegate(
+ [this, cbfunc = cb.as<sol::protected_function>()] () -> int
+ {
+ sol::optional<int> result(invoke(cbfunc));
+ if (result)
+ {
+ return result.value();
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] invalid return from element state callback\n");
+ return 0;
+ }
+ }));
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] must call set_element_state_callback with function or nil\n");
+ }
+ };
+ layout_view_item_type["set_animation_state_callback"] =
+ [this] (layout_view::item &i, sol::object cb)
+ {
+ if (cb == sol::lua_nil)
+ {
+ i.set_animation_state_callback(layout_view::item::state_delegate());
+ }
+ else if (cb.is<sol::protected_function>())
+ {
+ i.set_animation_state_callback(layout_view::item::state_delegate(
+ [this, cbfunc = cb.as<sol::protected_function>()] () -> int
+ {
+ sol::optional<int> result(invoke(cbfunc));
+ if (result)
+ {
+ return result.value();
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] invalid return from animation state callback\n");
+ return 0;
+ }
+ }));
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] must call set_animation_state_callback with function or nil\n");
+ }
+ };
+ layout_view_item_type["set_bounds_callback"] =
+ [this] (layout_view::item &i, sol::object cb)
+ {
+ if (cb == sol::lua_nil)
+ {
+ i.set_bounds_callback(layout_view::item::bounds_delegate());
+ }
+ else if (cb.is<sol::protected_function>())
+ {
+ i.set_bounds_callback(layout_view::item::bounds_delegate(
+ [this, cbfunc = cb.as<sol::protected_function>()] (render_bounds &b)
+ {
+ sol::optional<render_bounds> result(invoke(cbfunc));
+ if (result)
+ {
+ b = result.value();
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] invalid return from bounds callback\n");
+ b = render_bounds{ 0.0, 0.0, 1.0, 1.0 };
+ }
+ }));
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] must call set_bounds_callback with function or nil\n");
+ }
+ };
+ layout_view_item_type["set_color_callback"] =
+ [this] (layout_view::item &i, sol::object cb)
+ {
+ if (cb == sol::lua_nil)
+ {
+ i.set_color_callback(layout_view::item::color_delegate());
+ }
+ else if (cb.is<sol::protected_function>())
+ {
+ i.set_color_callback(layout_view::item::color_delegate(
+ [this, cbfunc = cb.as<sol::protected_function>()] (render_color &c)
+ {
+ sol::optional<render_color> result(invoke(cbfunc));
+ if (result)
+ {
+ c = result.value();
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] invalid return from color callback\n");
+ c = render_color{ 1.0, 1.0, 1.0, 1.0 };
+ }
+ }));
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] must call set_bounds_callback with function or nil\n");
+ }
+ };
+ layout_view_item_type["id"] = sol::property(
+ [this] (layout_view::item &i) -> sol::object
+ {
+ if (i.id().empty())
+ return sol::make_object(sol(), sol::lua_nil);
+ else
+ return sol::make_object(sol(), 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);
+ layout_view_item_type["bounds"] = sol::property(&layout_view::item::bounds);
+ layout_view_item_type["color"] = sol::property(&layout_view::item::color);
+ layout_view_item_type["blend_mode"] = sol::property(&layout_view::item::blend_mode);
+ layout_view_item_type["orientation"] = sol::property(&layout_view::item::orientation);
+ layout_view_item_type["element_state"] = sol::property(&layout_view::item::element_state);
+ layout_view_item_type["animation_state"] = sol::property(&layout_view::item::animation_state);
+
+
+/* layout_file library
+ *
+ * file.set_resolve_tags_callback - set additional tasks after resolving tags
+ *
+ * file.device - get device that caused the file to be loaded
+ * file.views[] - get view table (k=name, v=layout_view)
+ */
+
+ auto layout_file_type = sol().registry().new_usertype<layout_file>("layout_file", sol::no_constructor);
+ layout_file_type["set_resolve_tags_callback"] =
+ [this] (layout_file &f, sol::object cb)
+ {
+ if (cb == sol::lua_nil)
+ {
+ f.set_resolve_tags_callback(layout_file::resolve_tags_delegate());
+ }
+ else if (cb.is<sol::protected_function>())
+ {
+ f.set_resolve_tags_callback(layout_file::resolve_tags_delegate(
+ [this, cbfunc = cb.as<sol::protected_function>()] () { invoke(cbfunc); }));
+ }
+ else
+ {
+ osd_printf_error("[LUA ERROR] must call set_resolve_tags_callback with function or nil\n");
+ }
+ };
+ layout_file_type["device"] = sol::property(&layout_file::device);
+ layout_file_type["views"] = sol::property([] (layout_file &f) { return layout_file_views(f); });
+
+
/* render_target library
*
* manager:machine():render().targets[target_index]
* manager:machine():render():ui_target()
*
- * target:view_bounds() - get x0, x1, y0, y1 bounds for target
+ * target:current_view() - get current view for target
* target:width() - get target width
* target:height() - get target height
* target:pixel_aspect() - get target aspect
@@ -42,44 +599,41 @@ void lua_engine::initialize_render()
* target.zoom - enable zoom
*/
- auto target_type = sol().registry().new_usertype<render_target>("target", "new", sol::no_constructor);
- target_type.set("view_bounds", [](render_target &rt) {
- const render_bounds b = rt.current_view().bounds();
- return std::tuple<float, float, float, float>(b.x0, b.x1, b.y0, b.y1);
- });
- target_type.set("width", &render_target::width);
- target_type.set("height", &render_target::height);
- target_type.set("pixel_aspect", &render_target::pixel_aspect);
- target_type.set("hidden", &render_target::hidden);
- target_type.set("is_ui_target", &render_target::is_ui_target);
- target_type.set("index", &render_target::index);
- target_type.set("view_name", &render_target::view_name);
- target_type.set("max_update_rate", sol::property(&render_target::max_update_rate, &render_target::set_max_update_rate));
- target_type.set("view", sol::property(&render_target::view, &render_target::set_view));
- target_type.set("orientation", sol::property(&render_target::orientation, &render_target::set_orientation));
- target_type.set("screen_overlay", sol::property(&render_target::screen_overlay_enabled, &render_target::set_screen_overlay_enabled));
- target_type.set("zoom", sol::property(&render_target::zoom_to_screen, &render_target::set_zoom_to_screen));
+ auto target_type = sol().registry().new_usertype<render_target>("target", sol::no_constructor);
+ target_type["current_view"] = &render_target::current_view;
+ target_type["width"] = &render_target::width;
+ target_type["height"] = &render_target::height;
+ target_type["pixel_aspect"] = &render_target::pixel_aspect;
+ target_type["hidden"] = &render_target::hidden;
+ target_type["is_ui_target"] = &render_target::is_ui_target;
+ target_type["index"] = &render_target::index;
+ target_type["view_name"] = &render_target::view_name;
+ target_type["max_update_rate"] = sol::property(&render_target::max_update_rate, &render_target::set_max_update_rate);
+ target_type["view"] = sol::property(&render_target::view, &render_target::set_view);
+ target_type["orientation"] = sol::property(&render_target::orientation, &render_target::set_orientation);
+ target_type["screen_overlay"] = sol::property(&render_target::screen_overlay_enabled, &render_target::set_screen_overlay_enabled);
+ target_type["zoom"] = sol::property(&render_target::zoom_to_screen, &render_target::set_zoom_to_screen);
/* render_container library
*
* manager:machine():render():ui_container()
*
- * container:orientation()
- * container:xscale()
- * container:yscale()
- * container:xoffset()
- * container:yoffset()
- * container:is_empty()
+ * container.orientation
+ * container.xscale
+ * container.yscale
+ * container.xoffset
+ * container.yoffset
+ * container.is_empty
*/
- auto render_container_type = sol().registry().new_usertype<render_container>("render_container", "new", sol::no_constructor);
- render_container_type.set("orientation", &render_container::orientation);
- render_container_type.set("xscale", &render_container::xscale);
- render_container_type.set("yscale", &render_container::yscale);
- render_container_type.set("xoffset", &render_container::xoffset);
- render_container_type.set("yoffset", &render_container::yoffset);
- render_container_type.set("is_empty", &render_container::is_empty);
+ auto render_container_type = sol().registry().new_usertype<render_container>("render_container", sol::no_constructor);
+ render_container_type["orientation"] = sol::property(&render_container::orientation);
+ render_container_type["xscale"] = sol::property(&render_container::xscale);
+ render_container_type["yscale"] = sol::property(&render_container::yscale);
+ render_container_type["xoffset"] = sol::property(&render_container::xoffset);
+ render_container_type["yoffset"] = sol::property(&render_container::yoffset);
+ render_container_type["is_empty"] = sol::property(&render_container::is_empty);
/* render_manager library
@@ -93,16 +647,10 @@ void lua_engine::initialize_render()
* render.targets[] - render_target table
*/
- auto render_type = sol().registry().new_usertype<render_manager>("render", "new", sol::no_constructor);
- render_type.set("max_update_rate", &render_manager::max_update_rate);
- render_type.set("ui_target", &render_manager::ui_target);
- render_type.set("ui_container", &render_manager::ui_container);
- render_type.set("targets", sol::property([this](render_manager &r) {
- sol::table target_table = sol().create_table();
- int tc = 0;
- for(render_target &curr_rt : r.targets())
- target_table[tc++] = &curr_rt;
- return target_table;
- }));
+ auto render_type = sol().registry().new_usertype<render_manager>("render", sol::no_constructor);
+ render_type["max_update_rate"] = &render_manager::max_update_rate;
+ render_type["ui_target"] = &render_manager::ui_target;
+ render_type["ui_container"] = &render_manager::ui_container;
+ render_type["targets"] = sol::property([] (render_manager &m) { return render_manager_targets(m); });
}
diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp
index b996bae1dc0..a2a6a02f815 100644
--- a/src/frontend/mame/mame.cpp
+++ b/src/frontend/mame/mame.cpp
@@ -363,7 +363,7 @@ std::vector<std::reference_wrapper<const std::string>> mame_machine_manager::mis
assert(m_machine);
// make sure that any required image has a mounted file
- for (device_image_interface &image : image_interface_iterator(m_machine->root_device()))
+ for (device_image_interface &image : image_interface_enumerator(m_machine->root_device()))
{
if (image.must_be_loaded())
{
@@ -424,14 +424,20 @@ void emulator_info::sound_hook()
return mame_machine_manager::instance()->lua()->on_sound_update();
}
-void emulator_info::layout_file_cb(util::xml::data_node const &layout)
+void emulator_info::layout_script_cb(layout_file &file, const char *script)
{
- util::xml::data_node const *const mamelayout = layout.get_child("mamelayout");
- if (mamelayout)
+ // TODO: come up with a better way to pass multiple arguments to plugin
+ //mame_machine_manager::instance()->lua()->call_plugin_set("layout", std::make_tuple(&file, script->get_value()));
+ auto &lua(mame_machine_manager::instance()->lua()->sol());
+ sol::object obj = lua.registry()["cb_layout"];
+ if (obj.is<sol::protected_function>())
{
- util::xml::data_node const *const script = mamelayout->get_child("script");
- if (script)
- mame_machine_manager::instance()->lua()->call_plugin_set("layout", script->get_value());
+ auto res = obj.as<sol::protected_function>()(sol::make_reference(lua, &file), sol::make_reference(lua, script));
+ if (!res.valid())
+ {
+ sol::error err = res;
+ osd_printf_error("[LUA ERROR] in call_plugin: %s\n", err.what());
+ }
}
}
diff --git a/src/frontend/mame/mameopts.cpp b/src/frontend/mame/mameopts.cpp
index 296d900d679..88ae9951cd9 100644
--- a/src/frontend/mame/mameopts.cpp
+++ b/src/frontend/mame/mameopts.cpp
@@ -68,7 +68,7 @@ void mame_options::parse_standard_inis(emu_options &options, std::ostream &error
}
machine_config config(*cursystem, options);
- for (const screen_device &device : screen_device_iterator(config.root_device()))
+ for (const screen_device &device : screen_device_enumerator(config.root_device()))
{
// parse "raster.ini" for raster games
if (device.screen_type() == SCREEN_TYPE_RASTER)
diff --git a/src/frontend/mame/media_ident.cpp b/src/frontend/mame/media_ident.cpp
index 44b4271a7e5..9aeb8765089 100644
--- a/src/frontend/mame/media_ident.cpp
+++ b/src/frontend/mame/media_ident.cpp
@@ -353,7 +353,7 @@ void media_identifier::match_hashes(std::vector<file_info> &info)
}
// next iterate over softlists
- for (software_list_device &swlistdev : software_list_device_iterator(device))
+ for (software_list_device &swlistdev : software_list_device_enumerator(device))
{
if (!listnames.insert(swlistdev.list_name()).second)
continue;
diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp
index bd39e72a6cd..daf5afe1953 100644
--- a/src/frontend/mame/ui/datmenu.cpp
+++ b/src/frontend/mame/ui/datmenu.cpp
@@ -24,6 +24,7 @@
namespace ui {
+
//-------------------------------------------------
// ctor / dtor
//-------------------------------------------------
@@ -36,7 +37,7 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container
, m_issoft(false)
{
- for (device_image_interface& image : image_interface_iterator(mui.machine().root_device()))
+ for (device_image_interface& image : image_interface_enumerator(mui.machine().root_device()))
{
if (image.filename())
{
diff --git a/src/frontend/mame/ui/devctrl.h b/src/frontend/mame/ui/devctrl.h
index ecdbeedf736..1be2385a66f 100644
--- a/src/frontend/mame/ui/devctrl.h
+++ b/src/frontend/mame/ui/devctrl.h
@@ -17,15 +17,15 @@
submenu listing available devices of the same kind.
***************************************************************************/
-
-#pragma once
-
#ifndef MAME_FRONTEND_UI_DEVCTRL_H
#define MAME_FRONTEND_UI_DEVCTRL_H
+#pragma once
+
#include "ui/menu.h"
namespace ui {
+
template<class DeviceType>
class menu_device_control : public menu
{
@@ -43,8 +43,8 @@ protected:
uint32_t current_display_flags();
private:
- // device iterator
- typedef device_type_iterator<DeviceType> iterator;
+ // device enumerator
+ typedef device_type_enumerator<DeviceType> enumerator;
DeviceType * m_device;
int m_count;
@@ -59,7 +59,7 @@ template<class DeviceType>
menu_device_control<DeviceType>::menu_device_control(mame_ui_manager &mui, render_container &container, DeviceType *device)
: menu(mui, container)
{
- iterator iter(mui.machine().root_device());
+ enumerator iter(mui.machine().root_device());
m_count = iter.count();
m_device = device ? device : iter.first();
}
@@ -72,7 +72,7 @@ menu_device_control<DeviceType>::menu_device_control(mame_ui_manager &mui, rende
template<class DeviceType>
int menu_device_control<DeviceType>::current_index()
{
- iterator iter(machine().root_device());
+ enumerator iter(machine().root_device());
return iter.indexof(*m_device);
}
@@ -87,7 +87,7 @@ void menu_device_control<DeviceType>::previous()
// left arrow - rotate left through cassette devices
if (m_device != nullptr)
{
- iterator iter(machine().root_device());
+ enumerator iter(machine().root_device());
int index = iter.indexof(*m_device);
if (index > 0)
index--;
@@ -108,7 +108,7 @@ void menu_device_control<DeviceType>::next()
// right arrow - rotate right through cassette devices
if (m_device != nullptr)
{
- iterator iter(machine().root_device());
+ enumerator iter(machine().root_device());
int index = iter.indexof(*m_device);
if (index < m_count - 1)
index++;
@@ -154,4 +154,4 @@ uint32_t menu_device_control<DeviceType>::current_display_flags()
} // namespace ui
-#endif /* MAME_FRONTEND_UI_DEVCTRL_H */
+#endif // MAME_FRONTEND_UI_DEVCTRL_H
diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp
index 8688c513c6f..0172a65b3de 100644
--- a/src/frontend/mame/ui/devopt.cpp
+++ b/src/frontend/mame/ui/devopt.cpp
@@ -32,7 +32,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
machine_config &mconfig(const_cast<machine_config &>(machine().config()));
machine_config::token const tok(mconfig.begin_configuration(mconfig.root_device()));
device_t *const dev = mconfig.device_add(m_option->name(), m_option->devtype(), 0);
- for (device_t &d : device_iterator(*dev))
+ for (device_t &d : device_enumerator(*dev))
if (!d.configured())
d.config_complete();
@@ -46,7 +46,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
dev->name());
// loop over all CPUs
- execute_interface_iterator execiter(*dev);
+ execute_interface_enumerator execiter(*dev);
if (execiter.count() > 0)
{
str << _("* CPU:\n");
@@ -90,7 +90,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
}
// display screen information
- screen_device_iterator scriter(*dev);
+ screen_device_enumerator scriter(*dev);
if (scriter.count() > 0)
{
str << _("* Video:\n");
@@ -122,7 +122,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
}
// loop over all sound chips
- sound_interface_iterator snditer(*dev);
+ sound_interface_enumerator snditer(*dev);
if (snditer.count() > 0)
{
str << _("* Sound:\n");
@@ -192,7 +192,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
std::string errors;
std::ostringstream dips_opt, confs_opt;
ioport_list portlist;
- for (device_t &iptdev : device_iterator(*dev))
+ for (device_t &iptdev : device_enumerator(*dev))
portlist.append(iptdev, errors);
// check if the device adds inputs to the system
@@ -272,7 +272,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
if (input_keyboard)
util::stream_format(str, _(" Keyboard inputs [%1$d inputs]\n"), input_keyboard);
- image_interface_iterator imgiter(*dev);
+ image_interface_enumerator imgiter(*dev);
if (imgiter.count() > 0)
{
str << _("* Media Options:\n");
@@ -280,7 +280,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
util::stream_format(str, _(" %1$s [tag: %2$s]\n"), imagedev.image_type_name(), imagedev.device().tag());
}
- slot_interface_iterator slotiter(*dev);
+ slot_interface_enumerator slotiter(*dev);
if (slotiter.count() > 0)
{
str << _("* Slot Options:\n");
diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp
index cb3243e0544..6c5423746f8 100644
--- a/src/frontend/mame/ui/filemngr.cpp
+++ b/src/frontend/mame/ui/filemngr.cpp
@@ -116,14 +116,14 @@ void menu_file_manager::populate(float &customtop, float &custombottom)
// cycle through all devices for this system
std::unordered_set<std::string> devtags;
- for (device_t &dev : device_iterator(machine().root_device()))
+ for (device_t &dev : device_enumerator(machine().root_device()))
{
bool tag_appended = false;
if (!devtags.insert(dev.tag()).second)
continue;
// check whether it owns an image interface
- image_interface_iterator subiter(dev);
+ image_interface_enumerator subiter(dev);
if (subiter.first() != nullptr)
{
// if so, cycle through all its image interfaces
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index 6f30eea66f6..9bac109258a 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -82,7 +82,7 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf
{
ioport_list local_ports;
std::string sink;
- for (device_t &device : device_iterator(config.root_device()))
+ for (device_t &device : device_enumerator(config.root_device()))
{
// the "no sound hardware" warning doesn't make sense when you plug in a sound card
if (dynamic_cast<device_sound_interface *>(&device))
@@ -343,7 +343,7 @@ std::string machine_info::game_info_string() const
core_filename_extract_base(m_machine.system().type.source()));
// loop over all CPUs
- execute_interface_iterator execiter(m_machine.root_device());
+ execute_interface_enumerator execiter(m_machine.root_device());
std::unordered_set<std::string> exectags;
for (device_execute_interface &exec : execiter)
{
@@ -382,7 +382,7 @@ std::string machine_info::game_info_string() const
}
// loop over all sound chips
- sound_interface_iterator snditer(m_machine.root_device());
+ sound_interface_enumerator snditer(m_machine.root_device());
std::unordered_set<std::string> soundtags;
bool found_sound = false;
for (device_sound_interface &sound : snditer)
@@ -426,7 +426,7 @@ std::string machine_info::game_info_string() const
// display screen information
buf << _("\nVideo:\n");
- screen_device_iterator scriter(m_machine.root_device());
+ screen_device_enumerator scriter(m_machine.root_device());
int scrcount = scriter.count();
if (scrcount == 0)
buf << _("None\n");
@@ -468,7 +468,7 @@ std::string machine_info::game_info_string() const
std::string machine_info::get_screen_desc(screen_device &screen) const
{
- if (screen_device_iterator(m_machine.root_device()).count() > 1)
+ if (screen_device_enumerator(m_machine.root_device()).count() > 1)
return string_format(_("Screen '%1$s'"), screen.tag());
else
return _("Screen");
@@ -543,7 +543,7 @@ void menu_image_info::populate(float &customtop, float &custombottom)
item_append(machine().system().type.fullname(), "", FLAG_DISABLE, nullptr);
item_append("", "", FLAG_DISABLE, nullptr);
- for (device_image_interface &image : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
image_info(&image);
}
diff --git a/src/frontend/mame/ui/info_pty.cpp b/src/frontend/mame/ui/info_pty.cpp
index deed38ae932..49d0737cbad 100644
--- a/src/frontend/mame/ui/info_pty.cpp
+++ b/src/frontend/mame/ui/info_pty.cpp
@@ -30,7 +30,7 @@ void menu_pty_info::populate(float &customtop, float &custombottom)
item_append(_("Pseudo terminals"), "", FLAG_DISABLE, nullptr);
item_append("", "", FLAG_DISABLE, nullptr);
- for (device_pty_interface &pty : pty_interface_iterator(machine().root_device()))
+ for (device_pty_interface &pty : pty_interface_enumerator(machine().root_device()))
{
const char *port_name = pty.device().owner()->tag() + 1;
if (pty.is_open())
diff --git a/src/frontend/mame/ui/inifile.cpp b/src/frontend/mame/ui/inifile.cpp
index 028abc9c87b..253c52c07f3 100644
--- a/src/frontend/mame/ui/inifile.cpp
+++ b/src/frontend/mame/ui/inifile.cpp
@@ -470,7 +470,7 @@ void favorite_manager::apply_running_machine(running_machine &machine, T &&actio
else
{
bool have_software(false);
- for (device_image_interface &image_dev : image_interface_iterator(machine.root_device()))
+ for (device_image_interface &image_dev : image_interface_enumerator(machine.root_device()))
{
software_info const *const sw(image_dev.software_entry());
if (image_dev.exists() && image_dev.loaded_through_softlist() && sw)
diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp
index b1a0e238935..5c129f76397 100644
--- a/src/frontend/mame/ui/mainmenu.cpp
+++ b/src/frontend/mame/ui/mainmenu.cpp
@@ -79,7 +79,7 @@ void menu_main::populate(float &customtop, float &custombottom)
if (ui().found_machine_warnings())
item_append(_("Warning Information"), "", 0, (void *)WARN_INFO);
- for (device_image_interface &image : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
{
if (image.user_loadable())
{
@@ -91,22 +91,22 @@ void menu_main::populate(float &customtop, float &custombottom)
}
}
- if (cassette_device_iterator(machine().root_device()).first() != nullptr)
+ if (cassette_device_enumerator(machine().root_device()).first() != nullptr)
item_append(_("Tape Control"), "", 0, (void *)TAPE_CONTROL);
- if (pty_interface_iterator(machine().root_device()).first() != nullptr)
+ if (pty_interface_enumerator(machine().root_device()).first() != nullptr)
item_append(_("Pseudo terminals"), "", 0, (void *)PTY_INFO);
if (ui().machine_info().has_bioses())
item_append(_("BIOS Selection"), "", 0, (void *)BIOS_SELECTION);
- if (slot_interface_iterator(machine().root_device()).first() != nullptr)
+ if (slot_interface_enumerator(machine().root_device()).first() != nullptr)
item_append(_("Slot Devices"), "", 0, (void *)SLOT_DEVICES);
- if (barcode_reader_device_iterator(machine().root_device()).first() != nullptr)
+ if (barcode_reader_device_enumerator(machine().root_device()).first() != nullptr)
item_append(_("Barcode Reader"), "", 0, (void *)BARCODE_READ);
- if (network_interface_iterator(machine().root_device()).first() != nullptr)
+ if (network_interface_enumerator(machine().root_device()).first() != nullptr)
item_append(_("Network Devices"), "", 0, (void*)NETWORK_DEVICES);
if (machine().ioport().natkeyboard().keyboard_count())
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index e5c5d1862ae..1a6e95417ba 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -51,7 +51,7 @@ menu_bios_selection::menu_bios_selection(mame_ui_manager &mui, render_container
void menu_bios_selection::populate(float &customtop, float &custombottom)
{
// cycle through all devices for this system
- for (device_t &device : device_iterator(machine().root_device()))
+ for (device_t &device : device_enumerator(machine().root_device()))
{
device_t const *const parent(device.owner());
device_slot_interface const *const slot(dynamic_cast<device_slot_interface const *>(parent));
@@ -132,7 +132,7 @@ menu_network_devices::~menu_network_devices()
void menu_network_devices::populate(float &customtop, float &custombottom)
{
/* cycle through all devices for this system */
- for (device_network_interface &network : network_interface_iterator(machine().root_device()))
+ for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
{
int curr = network.get_interface();
const char *title = nullptr;
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index 13a63965f65..116ead68f94 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -790,7 +790,7 @@ void menu_select_game::inkey_select(const event *menu_event)
enumerator.next();
// if there are software entries, show a software selection menu
- for (software_list_device &swlistdev : software_list_device_iterator(enumerator.config()->root_device()))
+ for (software_list_device &swlistdev : software_list_device_enumerator(enumerator.config()->root_device()))
{
if (!swlistdev.get_info().empty())
{
@@ -863,7 +863,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
enumerator.next();
// if there are software entries, show a software selection menu
- for (software_list_device &swlistdev : software_list_device_iterator(enumerator.config()->root_device()))
+ for (software_list_device &swlistdev : software_list_device_enumerator(enumerator.config()->root_device()))
{
if (!swlistdev.get_info().empty())
{
diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp
index 5a14e3dac7f..ba3c33849e0 100644
--- a/src/frontend/mame/ui/selsoft.cpp
+++ b/src/frontend/mame/ui/selsoft.cpp
@@ -254,7 +254,7 @@ void menu_select_software::populate(float &customtop, float &custombottom)
// FIXME: why does it do this relatively expensive operation every time?
machine_config config(m_driver, machine().options());
- for (device_image_interface &image : image_interface_iterator(config.root_device()))
+ for (device_image_interface &image : image_interface_enumerator(config.root_device()))
{
if (!image.filename() && image.must_be_loaded())
{
@@ -351,7 +351,7 @@ void menu_select_software::build_software_list()
bool operator()(std::size_t a, std::size_t b) const { return swinfo[a].parentname < swinfo[b].parentname; };
};
orphan_less const orphan_cmp{ m_swinfo };
- for (software_list_device &swlist : software_list_device_iterator(config.root_device()))
+ for (software_list_device &swlist : software_list_device_enumerator(config.root_device()))
{
m_filter_data.add_list(swlist.list_name(), swlist.description());
check_for_icons(swlist.list_name().c_str());
@@ -381,7 +381,7 @@ void menu_select_software::build_software_list()
{
char const *instance_name(nullptr);
char const *type_name(nullptr);
- for (device_image_interface &image : image_interface_iterator(config.root_device()))
+ for (device_image_interface &image : image_interface_enumerator(config.root_device()))
{
char const *const interface = image.image_interface();
if (interface && part.matches_interface(interface))
diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp
index 01493173731..eac072bfa37 100644
--- a/src/frontend/mame/ui/slotopt.cpp
+++ b/src/frontend/mame/ui/slotopt.cpp
@@ -115,7 +115,7 @@ void menu_slot_devices::set_slot_device(device_slot_interface &slot, const char
void menu_slot_devices::record_current_options()
{
- for (device_slot_interface &slot : slot_interface_iterator(m_config->root_device()))
+ for (device_slot_interface &slot : slot_interface_enumerator(m_config->root_device()))
{
// we're doing this out of a desire to honor user-selectable options; therefore it only
// makes sense to record values for selectable options
@@ -177,7 +177,7 @@ void menu_slot_devices::populate(float &customtop, float &custombottom)
m_config = std::make_unique<machine_config>(machine().system(), machine().options());
// cycle through all devices for this system
- for (device_slot_interface &slot : slot_interface_iterator(m_config->root_device()))
+ for (device_slot_interface &slot : slot_interface_enumerator(m_config->root_device()))
{
// does this slot have any selectable options?
bool has_selectable_options = slot.has_selectable_options();
diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp
index bd2aa47aee5..d1e3f66da56 100644
--- a/src/frontend/mame/ui/swlist.cpp
+++ b/src/frontend/mame/ui/swlist.cpp
@@ -18,6 +18,7 @@
namespace ui {
+
/***************************************************************************
CONSTANTS
***************************************************************************/
@@ -355,7 +356,7 @@ void menu_software::populate(float &customtop, float &custombottom)
bool have_compatible = false;
// Add original software lists for this system
- software_list_device_iterator iter(machine().config().root_device());
+ software_list_device_enumerator iter(machine().config().root_device());
for (software_list_device &swlistdev : iter)
if (swlistdev.is_original())
if (!swlistdev.get_info().empty() && m_interface != nullptr)
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index 90efcb04b7c..948be161a28 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -446,7 +446,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
{
// non-critical warnings - map current unemulated/imperfect features
device_feature_set unemulated_features, imperfect_features;
- for (device_t &device : device_iterator(machine().root_device()))
+ for (device_t &device : device_enumerator(machine().root_device()))
{
device_t::feature_type unemulated = device.type().unemulated_features();
for (std::underlying_type_t<device_t::feature_type> feature = 1U; unemulated; feature <<= 1)
@@ -1167,7 +1167,7 @@ void mame_ui_manager::image_handler_ingame()
auto layout = create_layout(machine().render().ui_container());
// loop through all devices, build their text into the layout
- for (device_image_interface &image : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
{
std::string str = image.call_display();
if (!str.empty())
@@ -1315,7 +1315,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
// handle a tape control key
if (machine().ui_input().pressed(IPT_UI_TAPE_START))
{
- for (cassette_image_device &cass : cassette_device_iterator(machine().root_device()))
+ for (cassette_image_device &cass : cassette_device_enumerator(machine().root_device()))
{
cass.change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
return 0;
@@ -1323,7 +1323,7 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
}
if (machine().ui_input().pressed(IPT_UI_TAPE_STOP))
{
- for (cassette_image_device &cass : cassette_device_iterator(machine().root_device()))
+ for (cassette_image_device &cass : cassette_device_enumerator(machine().root_device()))
{
cass.change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
return 0;
@@ -1541,13 +1541,13 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
slider_index = 0;
if (machine.options().cheat())
{
- for (device_execute_interface &exec : execute_interface_iterator(machine.root_device()))
+ for (device_execute_interface &exec : execute_interface_enumerator(machine.root_device()))
{
void *param = (void *)&exec.device();
std::string str = string_format(_("Overclock CPU %1$s"), exec.device().tag());
m_sliders.push_back(slider_alloc(SLIDER_ID_OVERCLOCK + slider_index++, str.c_str(), 100, 1000, 4000, 10, param));
}
- for (device_sound_interface &snd : sound_interface_iterator(machine.root_device()))
+ for (device_sound_interface &snd : sound_interface_enumerator(machine.root_device()))
{
device_execute_interface *exec;
if (!snd.device().interface(exec) && snd.device().unscaled_clock() != 0)
@@ -1560,7 +1560,7 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
}
// add screen parameters
- screen_device_iterator scriter(machine.root_device());
+ screen_device_enumerator scriter(machine.root_device());
slider_index = 0;
for (screen_device &screen : scriter)
{
@@ -1599,7 +1599,7 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
}
slider_index = 0;
- for (laserdisc_device &laserdisc : laserdisc_device_iterator(machine.root_device()))
+ for (laserdisc_device &laserdisc : laserdisc_device_enumerator(machine.root_device()))
{
if (laserdisc.overlay_configured())
{
diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp
index fb3ecc1cacd..188c939c011 100644
--- a/src/frontend/mame/ui/viewgfx.cpp
+++ b/src/frontend/mame/ui/viewgfx.cpp
@@ -198,7 +198,7 @@ void ui_gfx_init(running_machine &machine)
static void ui_gfx_count_devices(running_machine &machine, ui_gfx_state &state)
{
// count the palette devices
- state.palette.devcount = palette_interface_iterator(machine.root_device()).count();
+ state.palette.devcount = palette_interface_enumerator(machine.root_device()).count();
// set the pointer to the first palette
if (state.palette.devcount > 0)
@@ -206,7 +206,7 @@ static void ui_gfx_count_devices(running_machine &machine, ui_gfx_state &state)
// count the gfx devices
state.gfxset.devcount = 0;
- for (device_gfx_interface &interface : gfx_interface_iterator(machine.root_device()))
+ for (device_gfx_interface &interface : gfx_interface_enumerator(machine.root_device()))
{
// count the gfx sets in each device, skipping devices with none
uint8_t count = 0;
@@ -371,7 +371,7 @@ cancel:
static void palette_set_device(running_machine &machine, ui_gfx_state &state)
{
- palette_interface_iterator pal_iter(machine.root_device());
+ palette_interface_enumerator pal_iter(machine.root_device());
state.palette.interface = pal_iter.byindex(state.palette.devindex);
}
@@ -1337,7 +1337,7 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state,
{
state.bitmap.fill(0);
tilemap_t *tilemap = machine.tilemap().find(state.tilemap.which);
- screen_device *first_screen = screen_device_iterator(machine.root_device()).first();
+ screen_device *first_screen = screen_device_enumerator(machine.root_device()).first();
if (first_screen)
{
tilemap->draw_debug(*first_screen, state.bitmap, state.tilemap.xoffs, state.tilemap.yoffs, state.tilemap.flags);