From 063e81d756b37fb97493c7da42c817bd7f6390aa Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 16 Oct 2019 18:31:48 +1100 Subject: (nw) add doxygen comments for a bunch of core stuff, and convert a bunch of comments to doxygen format --- src/emu/attotime.h | 2 +- src/emu/devfind.h | 14 +-- src/emu/device.h | 295 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/emu/disound.cpp | 34 +++--- src/emu/distate.cpp | 2 +- src/emu/emucore.h | 2 +- 6 files changed, 303 insertions(+), 46 deletions(-) (limited to 'src/emu') diff --git a/src/emu/attotime.h b/src/emu/attotime.h index c3efeca4ad5..cad95177724 100644 --- a/src/emu/attotime.h +++ b/src/emu/attotime.h @@ -369,4 +369,4 @@ inline attotime attotime::from_double(double _time) } -#endif // MAME_EMU_ATTOTIME_H +#endif // MAME_EMU_ATTOTIME_H diff --git a/src/emu/devfind.h b/src/emu/devfind.h index 2f90c48f370..b2993bf6361 100644 --- a/src/emu/devfind.h +++ b/src/emu/devfind.h @@ -1,13 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles, Vas Crabb -/** - * \file devfind.h - * Object auto-discovery helpers - * \defgroup devfind - * \{ - * Object auto-discovery helpers - */ - +/// \file +/// \brief Object auto-discovery helpers +/// \defgroup devfind Object auto-discovery helpers +/// \{ #ifndef __EMU_H__ #error Dont include this file directly; include emu.h instead. #endif @@ -1212,4 +1208,4 @@ extern template class shared_ptr_finder; extern template class shared_ptr_finder; #endif // MAME_EMU_DEVFIND_H -/** \} */ +/// \} diff --git a/src/emu/device.h b/src/emu/device.h index fc8da68f65c..257311deb7f 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -489,7 +489,34 @@ public: // device flags using feature = emu::detail::device_feature; using feature_type = emu::detail::device_feature::type; + + /// \brief Report unemulated features + /// + /// Implement this member in a derived class to declare features + /// that are not emulated. This will propagate to all other devices + /// and systems that use the device. Unemulated features are shown + /// in the system selection UI, and cause a red warning to be + /// displayed on starting a system. + /// \return Bitwise or of the feature constants for unemulated + /// features of the device. + /// \sa imperfect_features static constexpr feature_type unemulated_features() { return feature::NONE; } + + /// \brief Report imperfectly emulated features + /// + /// Implement this member in a derived class to declare features + /// that are imperfectly emulated. This will propagate to all other + /// devices and systems that use the device. Imperfectly emulated + /// features are shown in the system selection UI, and cause a + /// yellow warning to be displayed on starting a system (provided + /// there are no unemulated features, which take precedence and + /// cause the warning to be red). + /// + /// An exception is imperfectly emulated protection, which results + /// in a red warning being displayed when starting a system. + /// \return Bitwise or of the feature constants for imperfectly + /// emulated features of the device. + /// \sa unemulated_features static constexpr feature_type imperfect_features() { return feature::NONE; } virtual ~device_t(); @@ -616,15 +643,132 @@ protected: virtual const tiny_rom_entry *device_rom_region() const; virtual void device_add_mconfig(machine_config &config); virtual ioport_constructor device_input_ports() const; + + /// \brief Finalise device configuration + /// + /// Perform any final configuration tasks after all devices in the + /// system have added machine configuration. This is called after + /// any #device_interface mix-in interface_config_complete members + /// have completed. + /// + /// Note that automatic object finders will not have been resolved + /// at the time this member is called. virtual void device_config_complete(); + + /// \brief Additional device validity checks + /// + /// Implement this member to provide additional validity checks. + /// Report errors using #osd_printf_error and report warnings using + /// #osd_printf_warning. The system being validated, device type + /// and device tag are collected automatically. Do not throw + /// exceptions to report errors. + /// + /// This provides an opportunity to check that the device has been + /// configured correctly. Systems are validated on start, and also + /// when the user manually runs a validity check. Validity checks + /// are only run for devices configured in runnable systems, not + /// when checking that a device can be instantiated in isolation. + /// \param [in] valid Reference to the validity checker object + /// performing validation (provides some helper member functions). + /// \sa device_interface::interface_validity_check virtual void device_validity_check(validity_checker &valid) const ATTR_COLD; + + /// \brief Resolve objects that may be needed while starting + /// + /// Implement this member to complete object resolution before any + /// devices are started. For example it may be necessary to resolve + /// callbacks before any devices start so initial input conditions + /// can be set. This is called after all registerd automatic object + /// finders are resolved. virtual void device_resolve_objects() ATTR_COLD; + + /// \brief Device start handler + /// + /// Implement this member to set up the initial state of the device + /// on start. This will be called after all #device_interface + // /mix-in interface_pre_start members have completed successfully. + /// If the device can't start until another device has completed + /// starting, throw a #device_missing_dependencies exception. + /// Starting will be postponed until additional devices have been + /// started. + /// + /// If a device's base class is not device_t, it's good practice to + /// check start order dependencies (and throw + /// #device_missing_dependencies if necessary) before calling the + /// base implementation. This will ensure that the base + /// implementation won't be called twice if starting needs to be + /// postponed. + /// + /// This is the correct place to register for save states. + /// \sa device_reset device_stop + /// device_interface::interface_pre_start + /// device_interface::interface_post_start virtual void device_start() ATTR_COLD = 0; + + /// \brief Device stop handler + /// + /// Implement this member to perform additional tasks on ending an + /// emulation session. You may deallocate memory here. This is + /// called after interface_pre_stop is called for all + /// #device_interface mix-ins, and before interface_post_stop is + /// called for any #device_interface mix-ins. + /// \sa device_interface::interface_pre_stop + /// device_interface::interface_post_stop virtual void device_stop() ATTR_COLD; + + /// \brief Device reset handler + /// + /// Implement this member to provide reset behaviour. This is + /// called after all #device_interface mix-in interface_pre_reset + /// members have completed, and before any child devices are reset. + /// All devices are reset at the beginning of an emulation session + /// (after all devices have been started), and also when the user + /// requests a soft reset (by pressing F3 by default, and also + /// available from the debugger). + /// + /// Note that child devices are reset automatically when a device is + /// reset. You should not reset child devices manually from this + /// member. If you need to provide additional behaviour after child + /// devices are reset, implement #device_reset_after_children. + /// + /// Only implement warm reset behaviour in this member. Initial + /// cold reset conditions should be set up in #device_start. + /// \sa device_reset_after_children device_start + /// device_interface::interface_pre_reset + /// device_interface::interface_post_reset virtual void device_reset() ATTR_COLD; + + /// \brief Additional reset behaviour after child device reset + /// + /// Implement this member to provide additional reset behaviour + /// after child devices are reset. This is called when resetting a + /// device after #device_reset has been called and all child devices + /// have been reset, and before any #device_interface mix-in + /// interface_post_reset members are called. + /// \sa device_reset device_interface::interface_pre_reset + /// device_interface::interface_post_reset virtual void device_reset_after_children() ATTR_COLD; + + /// \brief Prepare for a save state to be written + /// + /// Implement this member to perform any tasks necessary before any + /// registered save state items are recorded. For example it may be + /// necessary to flush caches, serialise self-referencing members or + /// pointers into data structures. This is called after all + /// #device_interface mix-in interface_pre_save members are called. + /// \sa device_post_load device_interface::interface_pre_save virtual void device_pre_save() ATTR_COLD; + + /// \brief Complete save state loading + /// + /// Implement this member to perform any tasks necessary after + /// registered save state items are loaded. For example it may be + /// necessary to update or invalidate caches, or de-serialise + /// pointers into data structures. This is called after all + /// #device_interface mix-in interface_post_load members are called. + /// \sa device_pre_save device_interface::interface_post_load virtual void device_post_load() ATTR_COLD; + virtual void device_clock_changed(); virtual void device_debug_setup(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); @@ -677,9 +821,12 @@ private: }; -// ======================> device_interface - -// device_interface represents runtime information for a particular device interface +/// \brief Device mix-in base +/// +/// Provides a base for #device_t mix-ins that integrate with the device +/// lifecycle. Derived classes are used to implement a number of +/// standard concepts and interfaces, and integrate with the scheduler, +/// debugger and user interface. class device_interface { DISABLE_COPYING(device_interface); @@ -701,24 +848,138 @@ public: device_interface *interface_next() const { return m_interface_next; } // optional operation overrides - // - // WARNING: interface_pre_start must be callable multiple times in - // case another interface throws a missing dependency. In - // particular, state saving registrations should be done in post. + + /// \brief Finalise mix-in configuration + /// + /// Perform any final configuration tasks after all devices in the + /// system have added machine configuration. This is called before + /// device_config_complete is called for the device. + /// + /// Note that automatic object finders will not have been resolved + /// at this time. + /// \sa device_t::device_config_complete virtual void interface_config_complete(); - virtual void interface_validity_check(validity_checker &valid) const; - virtual void interface_pre_start(); - virtual void interface_post_start(); - virtual void interface_pre_reset(); - virtual void interface_post_reset(); - virtual void interface_pre_stop(); - virtual void interface_post_stop(); - virtual void interface_pre_save(); - virtual void interface_post_load(); + + /// \brief Additional mix-in validity checks + /// + /// Implement this member to provide additional validity checks. + /// Report errors using #osd_printf_error and report warnings using + /// #osd_printf_warning. The system being validated, device type + /// and device tag are collected automatically. Do not throw + /// exceptions to report errors. + /// + /// This provides an opportunity to check that the mix-in has been + /// configured correctly. Systems are validated on start, and also + /// when the user manually runs a validity check. Validity checks + /// are only run for devices configured in runnable systems, not + /// when checking that a device can be instantiated in isolation. + /// \param [in] valid Reference to the validity checker object + /// performing validation (provides some helper member functions). + /// \sa device_t::device_validity_check + virtual void interface_validity_check(validity_checker &valid) const ATTR_COLD; + + /// \brief Mix-in start handler + /// + /// Implement this member to set up the initial state of the mix-in + /// on start. This is called before the device_start member is + /// called for the device. If the mix-in can't be started until + /// another device has started, throw a #device_missing_dependencies + /// exception. Starting will be postponed until additional devices + /// have been started. + /// + /// Note that this member may be called multiple times if another + /// device_interface mix-in throws a #device_missing_dependencies + /// exception from its interface_pre_start member, or if the device + /// throws a #device_missing_dependencies exception from its + /// device_start member. You must check to ensure that operations + /// like resource allocation are not performed multiple times, or + /// postpone them until #interface_post_start is called. + /// + /// It's simpler to register for save states when + /// #interface_post_start is called. + /// \sa interface_post_start device_t::device_start + virtual void interface_pre_start() ATTR_COLD; + + /// \brief Mix-in start completion handler + /// + /// Implement this member to complete mix-in start-up. This is + /// called after #interface_pre_start is called for all + /// device_interface mix-ins, and after device_start is called for + /// the device. This member will only be called once, it will not + /// be called multiple times if device starting is postponed. + /// + /// This member must not throw #device_missing_dependencies (start + /// order dependencies should be checked in #interface_pre_start). + /// This is the appropriate place to allocate resources like + /// timers and register for save states. + /// \sa interface_pre_start device_t::device_start + virtual void interface_post_start() ATTR_COLD; + + /// \brief Mix-in reset handler + /// + /// Implement this member to provide reset behaviour. This is + /// called before device_reset is called for the device, and before + /// any child devices are reset. Only implement warm reset + /// behaviour in this member. Initial cold reset conditions should + /// be set up in #interface_pre_start and/or #interface_post_start. + /// If you need to provide additional behaviour after child devices + /// are reset, implement #interface_post_reset. + /// \sa interface_post_reset device_t::device_reset + virtual void interface_pre_reset() ATTR_COLD; + + /// \brief Mix-in reset completion handler + /// + /// Implement this member to provide additional reset behaviour + /// after child devices are reset. This is called after + /// device_reset_after_children has been called for the device. + /// \sa interface_pre_reset device_t::device_reset + /// device_t::device_reset_after_children + virtual void interface_post_reset() ATTR_COLD; + + /// \brief Mix-in stop handler + /// + /// Implement this member to perform additional tasks on ending an + /// emulation session. Do not deallocate anything that may need to + /// be referenced from another device_interface mix-in's + /// interface_pre_stop member or from the device's device_stop + /// member. This is called before device_stop is called for the + /// device. + /// \sa interface_post_stop device_t::device_stop + virtual void interface_pre_stop() ATTR_COLD; + + /// \brief Mix-in stop completion handler + /// + /// Implement this member to perform additional tasks on ending an + /// emulation session after the device is stopped. You can + /// deallocate memory here. This is called after device_stop is + /// called for the device. + /// \sa interface_pre_stop device_t::device_stop + virtual void interface_post_stop() ATTR_COLD; + + /// \brief Prepare for a save state to be written + /// + /// Implement this member to perform any tasks necessary before any + /// registered save state items are recorded. For example it may be + /// necessary to flush caches, serialise self-referencing members or + /// pointers into data structures. This is called before + /// device_pre_save is called for the device. + /// \sa interface_post_load device_t::device_pre_save + virtual void interface_pre_save() ATTR_COLD; + + /// \brief Complete save state loading + /// + /// Implement this member to perform any tasks necessary after + /// registered save state items are loaded. For example it may be + /// necessary to update or invalidate caches, or de-serialise + /// pointers into data structures. This is called before + /// device_post_load is called for the device. + /// \sa interface_pre_save device_t::device_post_load + virtual void interface_post_load() ATTR_COLD; + virtual void interface_clock_changed(); virtual void interface_debug_setup(); -protected: +private: // internal state device_interface * m_interface_next; device_t & m_device; diff --git a/src/emu/disound.cpp b/src/emu/disound.cpp index f3ab6b236f7..a8a0a55ad38 100644 --- a/src/emu/disound.cpp +++ b/src/emu/disound.cpp @@ -85,8 +85,8 @@ int device_sound_interface::inputs() const { // scan the list counting streams we own and summing their inputs int inputs = 0; - for (auto &stream : m_device.machine().sound().streams()) - if (&stream->device() == &m_device) + for (auto &stream : device().machine().sound().streams()) + if (&stream->device() == &device()) inputs += stream->input_count(); return inputs; } @@ -101,8 +101,8 @@ int device_sound_interface::outputs() const { // scan the list counting streams we own and summing their outputs int outputs = 0; - for (auto &stream : m_device.machine().sound().streams()) - if (&stream->device() == &m_device) + for (auto &stream : device().machine().sound().streams()) + if (&stream->device() == &device()) outputs += stream->output_count(); return outputs; } @@ -119,8 +119,8 @@ sound_stream *device_sound_interface::input_to_stream_input(int inputnum, int &s assert(inputnum >= 0); // scan the list looking for streams owned by this device - for (auto &stream : m_device.machine().sound().streams()) - if (&stream->device() == &m_device) + for (auto &stream : device().machine().sound().streams()) + if (&stream->device() == &device()) { if (inputnum < stream->input_count()) { @@ -146,7 +146,7 @@ sound_stream *device_sound_interface::output_to_stream_output(int outputnum, int assert(outputnum >= 0); // scan the list looking for streams owned by this device - for (auto &stream : m_device.machine().sound().streams()) + for (auto &stream : device().machine().sound().streams()) if (&stream->device() == &device()) { if (outputnum < stream->output_count()) @@ -212,7 +212,7 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) // handle ALL_OUTPUTS as a special case if (outputnum == ALL_OUTPUTS) { - for (auto &stream : m_device.machine().sound().streams()) + for (auto &stream : device().machine().sound().streams()) if (&stream->device() == &device()) for (int num = 0; num < stream->output_count(); num++) stream->set_output_gain(num, gain); @@ -237,7 +237,7 @@ void device_sound_interface::set_output_gain(int outputnum, float gain) int device_sound_interface::inputnum_from_device(device_t &source_device, int outputnum) const { int overall = 0; - for (auto &stream : m_device.machine().sound().streams()) + for (auto &stream : device().machine().sound().streams()) if (&stream->device() == &device()) for (int inputnum = 0; inputnum < stream->input_count(); inputnum++, overall++) if (stream->input_source_device(inputnum) == &source_device && stream->input_source_outputnum(inputnum) == outputnum) @@ -278,7 +278,7 @@ void device_sound_interface::interface_validity_check(validity_checker &valid) c void device_sound_interface::interface_pre_start() { // scan all the sound devices - sound_interface_iterator iter(m_device.machine().root_device()); + sound_interface_iterator iter(device().machine().root_device()); for (device_sound_interface const &sound : iter) { // scan each route on the device @@ -286,7 +286,7 @@ void device_sound_interface::interface_pre_start() { // see if we are the target of this route; if we are, make sure the source device is started device_t *const target_device = route.m_base.get().subdevice(route.m_target.c_str()); - if ((target_device == &m_device) && !sound.device().started()) + if ((target_device == &device()) && !sound.device().started()) throw device_missing_dependencies(); } } @@ -300,7 +300,7 @@ void device_sound_interface::interface_pre_start() { // see if we are the target of this route device_t *const target_device = route.m_base.get().subdevice(route.m_target.c_str()); - if ((target_device == &m_device) && (route.m_input == AUTO_ALLOC_INPUT)) + if ((target_device == &device()) && (route.m_input == AUTO_ALLOC_INPUT)) { route.m_input = m_auto_allocated_inputs; m_auto_allocated_inputs += (route.m_output == ALL_OUTPUTS) ? sound.outputs() : 1; @@ -318,14 +318,14 @@ void device_sound_interface::interface_pre_start() void device_sound_interface::interface_post_start() { // iterate over all the sound devices - for (device_sound_interface &sound : sound_interface_iterator(m_device.machine().root_device())) + for (device_sound_interface &sound : sound_interface_iterator(device().machine().root_device())) { // scan each route on the device for (sound_route const &route : sound.routes()) { // if we are the target of this route, hook it up device_t *const target_device = route.m_base.get().subdevice(route.m_target.c_str()); - if (target_device == &m_device) + if (target_device == &device()) { // iterate over all outputs, matching any that apply int inputnum = route.m_input; @@ -343,7 +343,7 @@ void device_sound_interface::interface_post_start() int streaminputnum; sound_stream *const inputstream = input_to_stream_input(inputnum++, streaminputnum); if (!inputstream) - fatalerror("Sound device '%s' targeted output #%d to nonexistent device '%s' input %d\n", sound.device().tag(), outputnum, m_device.tag(), inputnum - 1); + fatalerror("Sound device '%s' targeted output #%d to nonexistent device '%s' input %d\n", sound.device().tag(), outputnum, device().tag(), inputnum - 1); // set the input inputstream->set_input(streaminputnum, outputstream, streamoutputnum, route.m_gain); @@ -362,7 +362,7 @@ void device_sound_interface::interface_post_start() void device_sound_interface::interface_pre_reset() { // update all streams on this device prior to reset - for (auto &stream : m_device.machine().sound().streams()) + for (auto &stream : device().machine().sound().streams()) if (&stream->device() == &device()) stream->update(); } @@ -415,7 +415,7 @@ void device_mixer_interface::interface_pre_start() m_outputmap.resize(m_auto_allocated_inputs); // iterate through all routes that point to us and note their mixer output - for (device_sound_interface const &sound : sound_interface_iterator(m_device.machine().root_device())) + for (device_sound_interface const &sound : sound_interface_iterator(device().machine().root_device())) { for (sound_route const &route : sound.routes()) { diff --git a/src/emu/distate.cpp b/src/emu/distate.cpp index 2dcf4301ac4..b96d3c6aad3 100644 --- a/src/emu/distate.cpp +++ b/src/emu/distate.cpp @@ -624,7 +624,7 @@ void device_state_interface::interface_post_start() { // make sure we got something during startup if (m_state_list.size() == 0) - throw emu_fatalerror("No state registered for device '%s' that supports it!", m_device.tag()); + throw emu_fatalerror("No state registered for device '%s' that supports it!", device().tag()); } diff --git a/src/emu/emucore.h b/src/emu/emucore.h index 4c8b9c96056..92135e7ae84 100644 --- a/src/emu/emucore.h +++ b/src/emu/emucore.h @@ -373,4 +373,4 @@ inline u64 d2u(double d) return u.vv; } -#endif /* MAME_EMU_EMUCORE_H */ +#endif // MAME_EMU_EMUCORE_H -- cgit v1.2.3