// license:BSD-3-Clause // copyright-holders:Aaron Giles /***************************************************************************/ /** * @file mconfig.h * @defgroup MACHINE_CONFIG Machine configuration macros and functions * @{ */ /***************************************************************************/ #pragma once #ifndef __EMU_H__ #error Dont include this file directly; include emu.h instead. #endif #ifndef __MCONFIG_H__ #define __MCONFIG_H__ //************************************************************************** // CONSTANTS //************************************************************************** // by convention, tags should all be lowercase #define MIN_TAG_LENGTH 1 //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // forward references struct gfx_decode_entry; class driver_device; class screen_device; struct internal_layout { size_t decompressed_size; size_t compressed_size; UINT8 compression_type; const UINT8* data; }; // ======================> machine_config // machine configuration definition class machine_config { DISABLE_COPYING(machine_config); friend class running_machine; public: // construction/destruction machine_config(const game_driver &gamedrv, emu_options &options); ~machine_config(); // getters const game_driver &gamedrv() const { return m_gamedrv; } device_t &root_device() const { assert(m_root_device != nullptr); return *m_root_device; } screen_device *first_screen() const; emu_options &options() const { return m_options; } inline device_t *device(const char *tag) const { return root_device().subdevice(tag); } template inline _DeviceClass *device(const char *tag) const { return downcast<_DeviceClass *>(device(tag)); } // public state attotime m_minimum_quantum; // minimum scheduling quantum std::string m_perfect_cpu_quantum; // tag of CPU to use for "perfect" scheduling // other parameters const internal_layout * m_default_layout; // default layout for this machine // helpers during configuration; not for general use device_t *device_add(device_t *owner, const char *tag, device_type type, UINT32 clock); device_t *device_replace(device_t *owner, const char *tag, device_type type, UINT32 clock); device_t *device_remove(device_t *owner, const char *tag); device_t *device_find(device_t *owner, const char *tag); private: // internal helpers void remove_references(ATTR_UNUSED device_t &device); device_t &config_new_device(device_t &device); // internal state const game_driver & m_gamedrv; emu_options & m_options; std::unique_ptr m_root_device; }; //*************************************************************************/ /** @name Machine config start/end macros */ //*************************************************************************/ /** @def MACHINE_CONFIG_NAME(_name) Returns the internal name for the machine config. @param _name name of desired config @hideinitializer */ #define MACHINE_CONFIG_NAME(_name) construct_machine_config_##_name /** @def MACHINE_CONFIG_START(_name, _class) Begins a new machine config. @param _name name of this config @param _class driver_device class for this config @hideinitializer */ #define MACHINE_CONFIG_START(_name, _class) \ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ devcb_base *devcb = nullptr; \ (void)devcb; \ if (owner == nullptr) owner = config.device_add(nullptr, "root", &driver_device_creator<_class>, 0); /** @def MACHINE_CONFIG_FRAGMENT(_name) Begins a partial machine_config that can only be included in another "root" machine_config. This is also used for machine_configs that are specified as part of a device. @param _name name of this config fragment @hideinitializer */ #define MACHINE_CONFIG_FRAGMENT(_name) \ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ devcb_base *devcb = nullptr; \ (void)devcb; \ assert(owner != nullptr); /** @def MACHINE_CONFIG_DERIVED(_name, _base) Begins a machine_config that is derived from another machine_config. @param _name name of this config @param _base name of the parent config @hideinitializer */ #define MACHINE_CONFIG_DERIVED(_name, _base) \ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ devcb_base *devcb = nullptr; \ (void)devcb; \ owner = MACHINE_CONFIG_NAME(_base)(config, owner, device); \ assert(owner != nullptr); /** @def MACHINE_CONFIG_DERIVED_CLASS(_name, _base, _class) Begins a machine_config that is derived from another machine_config that can specify an alternate driver_device class @param _name name of this config @param _base name of the parent config @param _class name of the alternate driver_device class @hideinitializer */ #define MACHINE_CONFIG_DERIVED_CLASS(_name, _base, _class) \ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \ { \ devcb_base *devcb = nullptr; \ (void)devcb; \ if (owner == nullptr) owner = config.device_add(nullptr, "root", &driver_device_creator<_class>, 0); \ owner = MACHINE_CONFIG_NAME(_base)(config, owner, device); /** @def MACHINE_CONFIG_END Ends a machine_config. @hideinitializer */ #define MACHINE_CONFIG_END \ return owner; \ } //*************************************************************************/ /** @name Standalone machine config macros */ //*************************************************************************/ /** @def MACHINE_CONFIG_EXTERN(_name) References an external machine config. @param _name Name of the machine config to reference @hideinitializer */ #define MACHINE_CONFIG_EXTERN(_name) \ extern device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) //*************************************************************************/ /** @name Core machine config options */ //*************************************************************************/ // importing data from other machine drivers #define MCFG_FRAGMENT_ADD(_name) \ MACHINE_CONFIG_NAME(_name)(config, owner, device); // scheduling parameters #define MCFG_QUANTUM_TIME(_time) \ config.m_minimum_quantum = _time; #define MCFG_QUANTUM_PERFECT_CPU(_cputag) \ config.m_perfect_cpu_quantum = owner->subtag(_cputag); // core video parameters #define MCFG_DEFAULT_LAYOUT(_layout) \ config.m_default_layout = &(_layout); // add/remove devices #define MCFG_DEVICE_ADD(_tag, _type, _clock) \ device = config.device_add(owner, _tag, _type, _clock); #define MCFG_DEVICE_REPLACE(_tag, _type, _clock) \ device = config.device_replace(owner, _tag, _type, _clock); #define MCFG_DEVICE_REMOVE(_tag) \ device = config.device_remove(owner, _tag); #define MCFG_DEVICE_MODIFY(_tag) \ device = config.device_find(owner, _tag); #endif /* __MCONFIG_H__ */ /** @} */