mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +03:00

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.
148 lines
4.6 KiB
C++
148 lines
4.6 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Aaron Giles
|
|
/***************************************************************************
|
|
|
|
divideo.cpp
|
|
|
|
Device video interfaces.
|
|
|
|
***************************************************************************/
|
|
|
|
#include "emu.h"
|
|
#include "screen.h"
|
|
|
|
|
|
const char device_video_interface::s_unconfigured_screen_tag[] = "!!UNCONFIGURED!!";
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// DEVICE VIDEO INTERFACE
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// device_video_interface - constructor
|
|
//-------------------------------------------------
|
|
|
|
device_video_interface::device_video_interface(const machine_config &mconfig, device_t &device, bool screen_required)
|
|
: device_interface(device, "video")
|
|
, m_screen_required(screen_required)
|
|
, m_screen_base(&device)
|
|
, m_screen_tag(s_unconfigured_screen_tag)
|
|
, m_screen(nullptr)
|
|
{
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// ~device_video_interface - destructor
|
|
//-------------------------------------------------
|
|
|
|
device_video_interface::~device_video_interface()
|
|
{
|
|
}
|
|
|
|
|
|
void device_video_interface::set_screen(const char *tag)
|
|
{
|
|
m_screen_base = &device().mconfig().current_device();
|
|
m_screen_tag = tag;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// interface_config_complete - perform any
|
|
// operations now that the configuration is
|
|
// complete
|
|
//-------------------------------------------------
|
|
|
|
void device_video_interface::interface_config_complete()
|
|
{
|
|
// find the screen if explicitly configured
|
|
if (m_screen_tag && strcmp(m_screen_tag, s_unconfigured_screen_tag) != 0)
|
|
m_screen = m_screen_base->subdevice<screen_device>(m_screen_tag);
|
|
|
|
// device_config_complete may now do whatever it needs to with the screen
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// interface_validity_check - validation for a
|
|
// device after the configuration has been
|
|
// constructed
|
|
//-------------------------------------------------
|
|
|
|
void device_video_interface::interface_validity_check(validity_checker &valid) const
|
|
{
|
|
// only look up screens if we haven't explicitly requested no screen
|
|
screen_device *screen = nullptr;
|
|
if (m_screen_tag)
|
|
{
|
|
if (strcmp(m_screen_tag, s_unconfigured_screen_tag) != 0)
|
|
{
|
|
// find the screen device if explicitly configured
|
|
screen = m_screen_base->subdevice<screen_device>(m_screen_tag);
|
|
if (!screen)
|
|
osd_printf_error("Screen '%s' not found, explicitly set for device '%s'\n", m_screen_tag, device().tag());
|
|
}
|
|
else
|
|
{
|
|
// otherwise, look for a single match
|
|
screen_device_enumerator iter(device().mconfig().root_device());
|
|
screen = iter.first();
|
|
if (iter.count() > 1)
|
|
osd_printf_error("No screen specified for device '%s', but multiple screens found\n", device().tag());
|
|
}
|
|
}
|
|
|
|
// error if no screen is found
|
|
if (!screen && m_screen_required)
|
|
osd_printf_error("Device '%s' requires a screen\n", device().tag());
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// interface_pre_start - make sure all our input
|
|
// devices are started
|
|
//-------------------------------------------------
|
|
|
|
void device_video_interface::interface_pre_start()
|
|
{
|
|
// only look up screens if we haven't explicitly requested no screen
|
|
if (m_screen_tag)
|
|
{
|
|
if (strcmp(m_screen_tag, s_unconfigured_screen_tag) != 0)
|
|
{
|
|
// find the screen device if explicitly configured
|
|
m_screen = m_screen_base->subdevice<screen_device>(m_screen_tag);
|
|
if (!m_screen)
|
|
throw emu_fatalerror("Screen '%s' not found, explicitly set for device '%s'", m_screen_tag, device().tag());
|
|
}
|
|
else
|
|
{
|
|
// otherwise, look for a single match
|
|
screen_device_enumerator iter(device().machine().root_device());
|
|
m_screen = iter.first();
|
|
if (iter.count() > 1)
|
|
throw emu_fatalerror("No screen specified for device '%s', but multiple screens found", device().tag());
|
|
}
|
|
}
|
|
|
|
// fatal error if no screen is found
|
|
if (!m_screen && m_screen_required)
|
|
throw emu_fatalerror("Device '%s' requires a screen", device().tag());
|
|
|
|
// if we have a screen and it's not started, wait for it
|
|
if (m_screen && !m_screen->started())
|
|
{
|
|
// avoid circular dependency if we are also a palette device
|
|
device_palette_interface *palintf;
|
|
if (!device().interface(palintf))
|
|
throw device_missing_dependencies();
|
|
|
|
// no other palette may be specified
|
|
if (m_screen->has_palette() && palintf != &m_screen->palette())
|
|
throw emu_fatalerror("Device '%s' cannot control screen '%s' with palette '%s'", device().tag(), m_screen_tag, m_screen->palette().device().tag());
|
|
}
|
|
}
|