mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
Self-registering devices.
* MAME now walks all devices when generating -lx output irrespective of whether they're actually instantiated anywhere or not. * -lx is at least 30% faster than previous implementation. * Only possible drawback is that filtering drivers no longer filters devices.
This commit is contained in:
parent
8bf4bac0c1
commit
aa739563d1
@ -310,9 +310,7 @@ SLOT_INTERFACE_EXTERN( abcbus_cards );
|
||||
SLOT_INTERFACE_EXTERN( abc1600bus_cards );
|
||||
|
||||
|
||||
typedef device_type_iterator<ABCBUS_SLOT, abcbus_slot_t> abcbus_slot_device_iterator;
|
||||
|
||||
|
||||
typedef device_type_iterator<abcbus_slot_t> abcbus_slot_device_iterator;
|
||||
|
||||
|
||||
#endif // MAME_DEVICES_ABCBUS_ABCBUS_H
|
||||
|
@ -67,6 +67,6 @@ private:
|
||||
extern const device_type COCO_DWSOCK;
|
||||
|
||||
// device iterator
|
||||
typedef device_type_iterator<COCO_DWSOCK, beckerport_device> beckerport_device_iterator;
|
||||
typedef device_type_iterator<beckerport_device> beckerport_device_iterator;
|
||||
|
||||
#endif // MAME_DEVICES_BUS_COCO_DWSOCKH_H
|
||||
|
@ -1,6 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
|
||||
#include "emu.h"
|
||||
#include "bitsocket.h"
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
|
||||
#include "emu.h"
|
||||
#include "graphlinkhle.h"
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
|
||||
#include "emu.h"
|
||||
#include "teeconn.h"
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Vas Crabb
|
||||
|
||||
#include "emu.h"
|
||||
#include "tispeaker.h"
|
||||
|
||||
#include "speaker.h"
|
||||
|
@ -120,7 +120,7 @@ private:
|
||||
extern const device_type CASSETTE;
|
||||
|
||||
// device iterator
|
||||
typedef device_type_iterator<CASSETTE, cassette_image_device> cassette_device_iterator;
|
||||
typedef device_type_iterator<cassette_image_device> cassette_device_iterator;
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
|
@ -821,15 +821,18 @@ void legacy_floppy_image_device::device_start()
|
||||
void legacy_floppy_image_device::device_config_complete()
|
||||
{
|
||||
m_extension_list[0] = '\0';
|
||||
const struct FloppyFormat *floppy_options = m_config->formats;
|
||||
for (int i = 0; floppy_options[i].construct; i++)
|
||||
if (m_config)
|
||||
{
|
||||
// only add if creatable
|
||||
if (floppy_options[i].param_guidelines) {
|
||||
// allocate a new format and append it to the list
|
||||
add_format(floppy_options[i].name, floppy_options[i].description, floppy_options[i].extensions, floppy_options[i].param_guidelines);
|
||||
const struct FloppyFormat *floppy_options = m_config->formats;
|
||||
for (int i = 0; floppy_options && floppy_options[i].construct; i++)
|
||||
{
|
||||
// only add if creatable
|
||||
if (floppy_options[i].param_guidelines) {
|
||||
// allocate a new format and append it to the list
|
||||
add_format(floppy_options[i].name, floppy_options[i].description, floppy_options[i].extensions, floppy_options[i].param_guidelines);
|
||||
}
|
||||
image_specify_extension(m_extension_list, 256, floppy_options[i].extensions);
|
||||
}
|
||||
image_specify_extension( m_extension_list, 256, floppy_options[i].extensions );
|
||||
}
|
||||
|
||||
// set brief and instance name
|
||||
|
@ -73,6 +73,6 @@ private:
|
||||
extern const device_type MIDIIN;
|
||||
|
||||
// device iterator
|
||||
typedef device_type_iterator<MIDIIN, midiin_device> midiin_device_iterator;
|
||||
typedef device_type_iterator<midiin_device> midiin_device_iterator;
|
||||
|
||||
#endif /* __MIDIIN_H__ */
|
||||
|
@ -68,6 +68,6 @@ private:
|
||||
extern const device_type MIDIOUT;
|
||||
|
||||
// device iterator
|
||||
typedef device_type_iterator<MIDIOUT, midiout_device> midiout_device_iterator;
|
||||
typedef device_type_iterator<midiout_device> midiout_device_iterator;
|
||||
|
||||
#endif /* __MIDIOUT_H__ */
|
||||
|
@ -54,7 +54,7 @@ protected:
|
||||
extern const device_type BARCODE_READER;
|
||||
|
||||
// device type iterator
|
||||
typedef device_type_iterator<BARCODE_READER, barcode_reader_device> barcode_reader_device_iterator;
|
||||
typedef device_type_iterator<barcode_reader_device> barcode_reader_device_iterator;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -90,7 +90,7 @@ private:
|
||||
extern const device_type RAM;
|
||||
|
||||
// device iterator
|
||||
typedef device_type_iterator<RAM, ram_device> ram_device_iterator;
|
||||
typedef device_type_iterator<ram_device> ram_device_iterator;
|
||||
|
||||
extern template class device_finder<ram_device, false>;
|
||||
extern template class device_finder<ram_device, true>;
|
||||
|
@ -132,7 +132,7 @@ protected:
|
||||
};
|
||||
|
||||
// iterator, since lots of people are interested in these devices
|
||||
typedef device_type_iterator<SAMPLES, samples_device> samples_device_iterator;
|
||||
typedef device_type_iterator<samples_device> samples_device_iterator;
|
||||
|
||||
|
||||
// ======================> samples_iterator
|
||||
|
@ -15,6 +15,62 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE TYPE REGISTRATION
|
||||
//**************************************************************************
|
||||
|
||||
namespace emu { namespace detail {
|
||||
|
||||
namespace {
|
||||
|
||||
struct device_registrations
|
||||
{
|
||||
device_type_impl *first = nullptr;
|
||||
device_type_impl *last = nullptr;
|
||||
device_type_impl *unsorted = nullptr;
|
||||
};
|
||||
|
||||
device_registrations &device_registration_data()
|
||||
{
|
||||
// this is necessary to avoid issues with static initialisation order across units being indeterminate
|
||||
// thread safety issues are avoided by always calling this function during static initialisation before the app can go threaded
|
||||
static device_registrations instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
device_registrar::const_iterator device_registrar::cbegin() const
|
||||
{
|
||||
return const_iterator_helper(device_registration_data().first);
|
||||
}
|
||||
|
||||
|
||||
device_registrar::const_iterator device_registrar::cend() const
|
||||
{
|
||||
return const_iterator_helper(nullptr);
|
||||
}
|
||||
|
||||
|
||||
device_type_impl *device_registrar::register_device(device_type_impl &type)
|
||||
{
|
||||
device_registrations &data(device_registration_data());
|
||||
|
||||
if (!data.first) data.first = &type;
|
||||
if (data.last) data.last->m_next = &type;
|
||||
if (!data.unsorted) data.unsorted = &type;
|
||||
data.last = &type;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} } // namespace emu::detail
|
||||
|
||||
emu::detail::device_registrar const registered_device_types;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE MANAGEMENT
|
||||
//**************************************************************************
|
||||
|
287
src/emu/device.h
287
src/emu/device.h
@ -17,6 +17,13 @@
|
||||
#ifndef MAME_EMU_DEVICE_H
|
||||
#define MAME_EMU_DEVICE_H
|
||||
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -76,23 +83,156 @@ struct input_device_default;
|
||||
class finder_base;
|
||||
|
||||
|
||||
// exception classes
|
||||
class device_missing_dependencies : public emu_exception { };
|
||||
namespace emu { namespace detail {
|
||||
|
||||
class device_type_impl;
|
||||
|
||||
|
||||
// a device_type is simply a pointer to its alloc function
|
||||
typedef std::unique_ptr<device_t> (*device_type)(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
class device_registrar
|
||||
{
|
||||
private:
|
||||
class const_iterator_helper;
|
||||
|
||||
public:
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef device_type_impl value_type;
|
||||
typedef device_type_impl *pointer;
|
||||
typedef device_type_impl &reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
const_iterator() = default;
|
||||
const_iterator(const_iterator const &) = default;
|
||||
const_iterator &operator=(const_iterator const &) = default;
|
||||
|
||||
bool operator==(const_iterator const &that) const { return m_type == that.m_type; }
|
||||
bool operator!=(const_iterator const &that) const { return m_type != that.m_type; }
|
||||
reference operator*() const { assert(m_type); return *m_type; }
|
||||
pointer operator->() const { return m_type; }
|
||||
const_iterator &operator++();
|
||||
const_iterator operator++(int) { const_iterator const result(*this); ++*this; return result; }
|
||||
|
||||
private:
|
||||
friend class const_iterator_helper;
|
||||
|
||||
pointer m_type = nullptr;
|
||||
};
|
||||
|
||||
const_iterator begin() const { return cbegin(); }
|
||||
const_iterator end() const { return cend(); }
|
||||
const_iterator cbegin() const;
|
||||
const_iterator cend() const;
|
||||
|
||||
private:
|
||||
friend class device_type_impl;
|
||||
|
||||
class const_iterator_helper : public const_iterator
|
||||
{
|
||||
public:
|
||||
const_iterator_helper(device_type_impl *type) { m_type = type; }
|
||||
};
|
||||
|
||||
static device_type_impl *register_device(device_type_impl &type);
|
||||
};
|
||||
|
||||
|
||||
// this template function creates a stub which constructs a device
|
||||
template <class DeviceClass>
|
||||
std::unique_ptr<device_t> device_creator_impl(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
template <class DeviceClass> struct device_tag_struct { typedef DeviceClass type; };
|
||||
template <class DriverClass> struct driver_tag_struct { typedef DriverClass type; };
|
||||
|
||||
template <class DeviceClass> inline device_tag_struct<DeviceClass> device_tag_func() { return device_tag_struct<DeviceClass>{ }; }
|
||||
template <class DriverClass> inline driver_tag_struct<DriverClass> driver_tag_func() { return driver_tag_struct<DriverClass>{ }; }
|
||||
|
||||
class device_type_impl
|
||||
{
|
||||
private:
|
||||
friend class device_registrar;
|
||||
|
||||
typedef std::unique_ptr<device_t> (*create_func)(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
device_type_impl(device_type_impl const &) = delete;
|
||||
device_type_impl(device_type_impl &&) = delete;
|
||||
device_type_impl &operator=(device_type_impl const &) = delete;
|
||||
device_type_impl &operator=(device_type_impl &&) = delete;
|
||||
|
||||
// don't make these static member function templates inline
|
||||
template <typename DeviceClass> static std::unique_ptr<device_t> create_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
template <typename DriverClass> static std::unique_ptr<device_t> create_driver(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
create_func const m_creator;
|
||||
std::type_info const &m_type;
|
||||
device_type_impl *m_next;
|
||||
|
||||
public:
|
||||
device_type_impl(std::nullptr_t)
|
||||
: m_creator(nullptr)
|
||||
, m_type(typeid(nullptr_t))
|
||||
, m_next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <class DeviceClass> device_type_impl(device_tag_struct<DeviceClass> (*)())
|
||||
: m_creator(&create_device<DeviceClass>)
|
||||
, m_type(typeid(DeviceClass))
|
||||
, m_next(device_registrar::register_device(*this))
|
||||
{
|
||||
}
|
||||
|
||||
template <class DriverClass> device_type_impl(driver_tag_struct<DriverClass> (*)())
|
||||
: m_creator(&create_driver<DriverClass>)
|
||||
, m_type(typeid(DriverClass))
|
||||
, m_next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
std::type_info const &type() const { return m_type; }
|
||||
|
||||
std::unique_ptr<device_t> operator()(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) const
|
||||
{
|
||||
return m_creator(mconfig, tag, owner, clock);
|
||||
}
|
||||
|
||||
explicit operator bool() const { return bool(m_creator); }
|
||||
bool operator==(device_type_impl const &that) const { return &that == this; }
|
||||
bool operator!=(device_type_impl const &that) const { return &that != this; }
|
||||
};
|
||||
|
||||
|
||||
inline device_registrar::const_iterator &device_registrar::const_iterator::operator++() { m_type = m_type->m_next; return *this; }
|
||||
|
||||
|
||||
template <typename DeviceClass>
|
||||
std::unique_ptr<device_t> device_type_impl::create_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
{
|
||||
return make_unique_clear<DeviceClass>(mconfig, tag, owner, clock);
|
||||
}
|
||||
|
||||
template <class DeviceClass>
|
||||
constexpr device_type device_creator = &device_creator_impl<DeviceClass>;
|
||||
template <typename DriverClass>
|
||||
std::unique_ptr<device_t> device_type_impl::create_driver(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
{
|
||||
assert(!owner);
|
||||
assert(!clock);
|
||||
|
||||
// this is not thread-safe
|
||||
// we can get away with it because driver creators aren't registered
|
||||
// hence all members are initialised with constant values and the race won't cause issues
|
||||
static device_type_impl const &driver_type = &driver_tag_func<DriverClass>;
|
||||
return make_unique_clear<DriverClass>(mconfig, driver_type, tag);
|
||||
}
|
||||
|
||||
} } // namespace emu::detail
|
||||
|
||||
|
||||
// device types
|
||||
typedef emu::detail::device_type_impl const &device_type;
|
||||
template <class DeviceClass> constexpr auto device_creator = &emu::detail::device_tag_func<DeviceClass>;
|
||||
template <class DriverClass> constexpr auto driver_device_creator = &emu::detail::driver_tag_func<DriverClass>;
|
||||
extern emu::detail::device_registrar const registered_device_types;
|
||||
|
||||
|
||||
// exception classes
|
||||
class device_missing_dependencies : public emu_exception { };
|
||||
|
||||
|
||||
// timer IDs for devices
|
||||
@ -448,57 +588,68 @@ public:
|
||||
class auto_iterator
|
||||
{
|
||||
public:
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef device_t value_type;
|
||||
typedef device_t *pointer;
|
||||
typedef device_t &reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
// construction
|
||||
auto_iterator(device_t *devptr, int curdepth, int maxdepth)
|
||||
: m_curdevice(devptr)
|
||||
, m_curdepth(curdepth)
|
||||
, m_maxdepth(maxdepth)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
// getters
|
||||
device_t *current() const { return m_curdevice; }
|
||||
int depth() const { return m_curdepth; }
|
||||
|
||||
// required operator overrides
|
||||
bool operator!=(const auto_iterator &iter) const { return m_curdevice != iter.m_curdevice; }
|
||||
device_t &operator*() const { assert(m_curdevice != nullptr); return *m_curdevice; }
|
||||
const auto_iterator &operator++() { advance(); return *this; }
|
||||
bool operator==(auto_iterator const &iter) const { return m_curdevice == iter.m_curdevice; }
|
||||
bool operator!=(auto_iterator const &iter) const { return m_curdevice != iter.m_curdevice; }
|
||||
device_t &operator*() const { assert(m_curdevice); return *m_curdevice; }
|
||||
device_t *operator->() const { return m_curdevice; }
|
||||
auto_iterator &operator++() { advance(); return *this; }
|
||||
auto_iterator operator++(int) { auto_iterator const result(*this); ++*this; return result; }
|
||||
|
||||
protected:
|
||||
// search depth-first for the next device
|
||||
void advance()
|
||||
{
|
||||
// remember our starting position, and end immediately if we're nullptr
|
||||
device_t *start = m_curdevice;
|
||||
if (start == nullptr)
|
||||
return;
|
||||
|
||||
// search down first
|
||||
if (m_curdepth < m_maxdepth)
|
||||
if (m_curdevice)
|
||||
{
|
||||
m_curdevice = start->subdevices().first();
|
||||
if (m_curdevice != nullptr)
|
||||
device_t *start = m_curdevice;
|
||||
|
||||
// search down first
|
||||
if (m_curdepth < m_maxdepth)
|
||||
{
|
||||
m_curdepth++;
|
||||
return;
|
||||
m_curdevice = start->subdevices().first();
|
||||
if (m_curdevice)
|
||||
{
|
||||
m_curdepth++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// search next for neighbors up the ownership chain
|
||||
while (m_curdepth > 0 && start)
|
||||
{
|
||||
// found a neighbor? great!
|
||||
m_curdevice = start->next();
|
||||
if (m_curdevice)
|
||||
return;
|
||||
|
||||
// no? try our parent
|
||||
start = start->owner();
|
||||
m_curdepth--;
|
||||
}
|
||||
|
||||
// returned to the top; we're done
|
||||
m_curdevice = nullptr;
|
||||
}
|
||||
|
||||
// search next for neighbors up the ownership chain
|
||||
while (m_curdepth > 0 && start != nullptr)
|
||||
{
|
||||
// found a neighbor? great!
|
||||
m_curdevice = start->next();
|
||||
if (m_curdevice != nullptr)
|
||||
return;
|
||||
|
||||
// no? try our parent
|
||||
start = start->owner();
|
||||
m_curdepth--;
|
||||
}
|
||||
|
||||
// returned to the top; we're done
|
||||
m_curdevice = nullptr;
|
||||
}
|
||||
|
||||
// protected state
|
||||
@ -563,65 +714,71 @@ private:
|
||||
// ======================> device_type_iterator
|
||||
|
||||
// helper class to find devices of a given type in the device hierarchy
|
||||
template <device_type const &_DeviceType, class _DeviceClass = device_t>
|
||||
template <class DeviceType, class DeviceClass = DeviceType>
|
||||
class device_type_iterator
|
||||
{
|
||||
public:
|
||||
class auto_iterator : public device_iterator::auto_iterator
|
||||
class auto_iterator : protected device_iterator::auto_iterator
|
||||
{
|
||||
public:
|
||||
public:
|
||||
using device_iterator::auto_iterator::difference_type;
|
||||
using device_iterator::auto_iterator::iterator_category;
|
||||
using device_iterator::auto_iterator::depth;
|
||||
|
||||
typedef DeviceClass value_type;
|
||||
typedef DeviceClass *pointer;
|
||||
typedef DeviceClass &reference;
|
||||
|
||||
// construction
|
||||
auto_iterator(device_t *devptr, int curdepth, int maxdepth)
|
||||
: device_iterator::auto_iterator(devptr, curdepth, maxdepth)
|
||||
{
|
||||
// make sure the first device is of the specified type
|
||||
while (m_curdevice && (m_curdevice->type() != _DeviceType))
|
||||
while (m_curdevice && (m_curdevice->type().type() != typeid(DeviceType)))
|
||||
advance();
|
||||
}
|
||||
|
||||
// required operator overrides
|
||||
bool operator==(auto_iterator const &iter) const { return m_curdevice == iter.m_curdevice; }
|
||||
bool operator!=(auto_iterator const &iter) const { return m_curdevice != iter.m_curdevice; }
|
||||
|
||||
// getters returning specified device type
|
||||
_DeviceClass *current() const { return downcast<_DeviceClass *>(m_curdevice); }
|
||||
_DeviceClass &operator*() const { assert(m_curdevice != nullptr); return downcast<_DeviceClass &>(*m_curdevice); }
|
||||
DeviceClass *current() const { return downcast<DeviceClass *>(m_curdevice); }
|
||||
DeviceClass &operator*() const { assert(m_curdevice); return downcast<DeviceClass &>(*m_curdevice); }
|
||||
DeviceClass *operator->() const { return downcast<DeviceClass *>(m_curdevice); }
|
||||
|
||||
// search for devices of the specified type
|
||||
const auto_iterator &operator++()
|
||||
auto_iterator &operator++()
|
||||
{
|
||||
advance();
|
||||
while (m_curdevice != nullptr && m_curdevice->type() != _DeviceType)
|
||||
while (m_curdevice && (m_curdevice->type().type() != typeid(DeviceType)))
|
||||
advance();
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto_iterator operator++(int) { auto_iterator const result(*this); ++*this; return result; }
|
||||
};
|
||||
|
||||
public:
|
||||
// construction
|
||||
device_type_iterator(device_t &root, int maxdepth = 255)
|
||||
: m_root(root), m_maxdepth(maxdepth) { }
|
||||
device_type_iterator(device_t &root, int maxdepth = 255) : m_root(root), m_maxdepth(maxdepth) { }
|
||||
|
||||
// standard iterators
|
||||
auto_iterator begin() const { return auto_iterator(&m_root, 0, m_maxdepth); }
|
||||
auto_iterator end() const { return auto_iterator(nullptr, 0, m_maxdepth); }
|
||||
auto_iterator cbegin() const { return auto_iterator(&m_root, 0, m_maxdepth); }
|
||||
auto_iterator cend() const { return auto_iterator(nullptr, 0, m_maxdepth); }
|
||||
|
||||
// return first item
|
||||
_DeviceClass *first() const { return begin().current(); }
|
||||
DeviceClass *first() const { return begin().current(); }
|
||||
|
||||
// return the number of items available
|
||||
int count() const
|
||||
{
|
||||
int result = 0;
|
||||
for (_DeviceClass &item : *this)
|
||||
{
|
||||
(void)&item;
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int count() const { return std::distance(cbegin(), cend()); }
|
||||
|
||||
// return the index of a given item in the virtual list
|
||||
int indexof(_DeviceClass &device) const
|
||||
int indexof(DeviceClass &device) const
|
||||
{
|
||||
int index = 0;
|
||||
for (_DeviceClass &item : *this)
|
||||
for (DeviceClass &item : *this)
|
||||
{
|
||||
if (&item == &device)
|
||||
return index;
|
||||
@ -632,9 +789,9 @@ public:
|
||||
}
|
||||
|
||||
// return the indexed item in the list
|
||||
_DeviceClass *byindex(int index) const
|
||||
DeviceClass *byindex(int index) const
|
||||
{
|
||||
for (_DeviceClass &item : *this)
|
||||
for (DeviceClass &item : *this)
|
||||
if (index-- == 0)
|
||||
return &item;
|
||||
return nullptr;
|
||||
|
@ -1321,8 +1321,8 @@ void device_image_interface::update_names(const device_type device_type, const c
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instance_name = inst_name;
|
||||
m_brief_instance_name = brief_name;
|
||||
m_instance_name = inst_name ? inst_name : "";
|
||||
m_brief_instance_name = brief_name ? brief_name : "";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,17 +225,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// this template function creates a stub which constructs a device
|
||||
template<class DriverClass>
|
||||
std::unique_ptr<device_t> driver_device_creator_impl(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
{
|
||||
assert(owner == nullptr);
|
||||
assert(clock == 0);
|
||||
return make_unique_clear<DriverClass>(mconfig, &driver_device_creator_impl<DriverClass>, tag);
|
||||
}
|
||||
|
||||
template <class DriverClass>
|
||||
constexpr device_type driver_device_creator = &driver_device_creator_impl<DriverClass>;
|
||||
|
||||
|
||||
#endif /* MAME_EMU_DRIVER_H */
|
||||
|
@ -523,7 +523,7 @@ private:
|
||||
};
|
||||
|
||||
// device type iterator
|
||||
typedef device_type_iterator<PALETTE, palette_device> palette_device_iterator;
|
||||
typedef device_type_iterator<palette_device> palette_device_iterator;
|
||||
|
||||
|
||||
#endif // MAME_EMU_EMUPAL_H
|
||||
|
@ -365,7 +365,7 @@ private:
|
||||
extern const device_type SCREEN;
|
||||
|
||||
// iterator helper
|
||||
typedef device_type_iterator<SCREEN, screen_device> screen_device_iterator;
|
||||
typedef device_type_iterator<screen_device> screen_device_iterator;
|
||||
|
||||
extern template class device_finder<screen_device, false>;
|
||||
extern template class device_finder<screen_device, true>;
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __SOFTLIST_DEV_H_
|
||||
#define __SOFTLIST_DEV_H_
|
||||
#ifndef MAME_EMU_SOFTLIST_DEV
|
||||
#define MAME_EMU_SOFTLIST_DEV
|
||||
|
||||
#include "softlist.h"
|
||||
|
||||
@ -189,7 +189,7 @@ private:
|
||||
extern const device_type SOFTWARE_LIST;
|
||||
|
||||
// device type iterator
|
||||
typedef device_type_iterator<SOFTWARE_LIST, software_list_device> software_list_device_iterator;
|
||||
typedef device_type_iterator<software_list_device> software_list_device_iterator;
|
||||
|
||||
|
||||
#endif // __SOFTLIST_DEV_H_
|
||||
#endif // MAME_EMU_SOFTLIST_DEV
|
||||
|
@ -77,7 +77,7 @@ protected:
|
||||
|
||||
|
||||
// speaker device iterator
|
||||
typedef device_type_iterator<SPEAKER, speaker_device> speaker_device_iterator;
|
||||
typedef device_type_iterator<speaker_device> speaker_device_iterator;
|
||||
|
||||
extern template class device_finder<speaker_device, false>;
|
||||
extern template class device_finder<speaker_device, true>;
|
||||
|
@ -377,7 +377,7 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag)
|
||||
for (ioport_field &field : port.second->fields())
|
||||
if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
|
||||
{
|
||||
has_input = true;
|
||||
has_input = true; break;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -427,51 +427,25 @@ void info_xml_creator::output_one_device(device_t &device, const char *devtag)
|
||||
|
||||
void info_xml_creator::output_devices()
|
||||
{
|
||||
// get config for some arbitrary machine
|
||||
m_drivlist.reset();
|
||||
std::unordered_set<std::string> shortnames;
|
||||
m_drivlist.next();
|
||||
std::shared_ptr<machine_config> config = m_drivlist.config();
|
||||
|
||||
while (m_drivlist.next())
|
||||
// run through devices
|
||||
for (device_type type : registered_device_types)
|
||||
{
|
||||
// first, run through devices with roms which belongs to the default configuration
|
||||
for (device_t &device : device_iterator(m_drivlist.config()->root_device()))
|
||||
{
|
||||
if (device.owner() != nullptr && device.shortname() != nullptr && device.shortname()[0]!='\0')
|
||||
{
|
||||
if (shortnames.insert(device.shortname()).second)
|
||||
output_one_device(device, device.tag());
|
||||
}
|
||||
}
|
||||
// add it at the root of the machine config
|
||||
device_t *const dev = config->device_add(&config->root_device(), "_tmp", type, 0);
|
||||
|
||||
// then, run through slot devices
|
||||
for (const device_slot_interface &slot : slot_interface_iterator(m_drivlist.config()->root_device()))
|
||||
{
|
||||
for (auto &option : slot.option_list())
|
||||
{
|
||||
std::string temptag("_");
|
||||
temptag.append(option.second->name());
|
||||
device_t *dev = m_drivlist.config()->device_add(&m_drivlist.config()->root_device(), temptag.c_str(), option.second->devtype(), 0);
|
||||
// notify this device and all its subdevices that they are now configured
|
||||
for (device_t &device : device_iterator(*dev))
|
||||
if (!device.configured())
|
||||
device.config_complete();
|
||||
|
||||
// notify this device and all its subdevices that they are now configured
|
||||
for (device_t &device : device_iterator(*dev))
|
||||
if (!device.configured())
|
||||
device.config_complete();
|
||||
|
||||
if (shortnames.insert(dev->shortname()).second)
|
||||
output_one_device(*dev, temptag.c_str());
|
||||
|
||||
// also, check for subdevices with ROMs (a few devices are missed otherwise, e.g. MPU401)
|
||||
for (device_t &device : device_iterator(*dev))
|
||||
{
|
||||
if (device.owner() == dev && device.shortname() != nullptr && device.shortname()[0]!='\0')
|
||||
{
|
||||
if (shortnames.insert(device.shortname()).second)
|
||||
output_one_device(device, device.tag());
|
||||
}
|
||||
}
|
||||
|
||||
m_drivlist.config()->device_remove(&m_drivlist.config()->root_device(), temptag.c_str());
|
||||
}
|
||||
}
|
||||
// print details and remove it
|
||||
output_one_device(*dev, dev->tag());
|
||||
config->device_remove(&config->root_device(), "_tmp");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,7 @@ protected:
|
||||
|
||||
private:
|
||||
// device iterator
|
||||
static constexpr device_type TYPE = device_creator<DeviceType>;
|
||||
typedef device_type_iterator<TYPE, DeviceType> iterator;
|
||||
typedef device_type_iterator<DeviceType> iterator;
|
||||
|
||||
DeviceType * m_device;
|
||||
int m_count;
|
||||
|
@ -258,13 +258,15 @@ vis_vga_device::vis_vga_device(const machine_config &mconfig, const char *tag, d
|
||||
: svga_device(mconfig, VIS_VGA, "vis_vga", tag, owner, clock, "vis_vga", __FILE__),
|
||||
device_isa16_card_interface(mconfig, *this)
|
||||
{
|
||||
m_palette.set_tag("palette");
|
||||
m_screen.set_tag("screen");
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( vis_vga_config )
|
||||
MCFG_SCREEN_ADD(":visvga:screen", RASTER)
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS(XTAL_25_1748MHz,900,0,640,526,0,480)
|
||||
MCFG_SCREEN_UPDATE_DEVICE("visvga", vis_vga_device, screen_update)
|
||||
MCFG_PALETTE_ADD(":visvga:palette", 0x100)
|
||||
MCFG_PALETTE_ADD("palette", 0x100)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor vis_vga_device::device_mconfig_additions() const
|
||||
|
Loading…
Reference in New Issue
Block a user