diff options
author | Vas Crabb <vas@vastheman.com> | 2019-12-09 19:07:22 +1100 |
---|---|---|
committer | Vas Crabb <vas@vastheman.com> | 2019-12-09 19:09:51 +1100 |
commit | d27918db8c5a503c7f272e1d4539a410d4807df3 (patch) | |
tree | ebdd7ca84bd244b88b78c4a7e5a2c313c84becec | |
parent | 017b53b2f58fa3c1b3e0b74d23f248892256dad5 (diff) |
Added wrapper for using STRUCT_MEMBER with an indeterminate length array
* Examples in YM2612 family and MultiPCM
* Also used STRUCT_MEMBER to reduce clutter in diexec save state registration
-rw-r--r-- | src/devices/sound/fm2612.cpp | 21 | ||||
-rw-r--r-- | src/devices/sound/multipcm.cpp | 26 | ||||
-rw-r--r-- | src/devices/sound/multipcm.h | 1 | ||||
-rw-r--r-- | src/emu/device.h | 6 | ||||
-rw-r--r-- | src/emu/diexec.cpp | 15 | ||||
-rw-r--r-- | src/emu/diexec.h | 4 | ||||
-rw-r--r-- | src/emu/save.h | 15 |
7 files changed, 48 insertions, 40 deletions
diff --git a/src/devices/sound/fm2612.cpp b/src/devices/sound/fm2612.cpp index 91d27686fe0..7923e46ccbb 100644 --- a/src/devices/sound/fm2612.cpp +++ b/src/devices/sound/fm2612.cpp @@ -1697,21 +1697,16 @@ static inline void CSMKeyControll(fm2612_FM_OPN *OPN, fm2612_FM_CH *CH) /* FM channel save , internal state only */ static void FMsave_state_channel(device_t *device,fm2612_FM_CH *CH,int num_ch) { - int slot , ch; + /* channel */ + device->save_pointer(STRUCT_MEMBER(CH, op1_out), num_ch); + device->save_pointer(STRUCT_MEMBER(CH, fc), num_ch); - for(ch=0;ch<num_ch;ch++,CH++) + /* slots */ + for(int ch=0;ch<num_ch;ch++,CH++) { - /* channel */ - device->save_item(NAME(CH->op1_out), ch); - device->save_item(NAME(CH->fc), ch); - /* slots */ - for(slot=0;slot<4;slot++) - { - fm2612_FM_SLOT *SLOT = &CH->SLOT[slot]; - device->save_item(NAME(SLOT->phase), ch * 4 + slot); - device->save_item(NAME(SLOT->state), ch * 4 + slot); - device->save_item(NAME(SLOT->volume), ch * 4 + slot); - } + device->save_item(STRUCT_MEMBER(CH->SLOT, phase), ch); + device->save_item(STRUCT_MEMBER(CH->SLOT, state), ch); + device->save_item(STRUCT_MEMBER(CH->SLOT, volume), ch); } } diff --git a/src/devices/sound/multipcm.cpp b/src/devices/sound/multipcm.cpp index 285b6ade701..ca8b179ac5d 100644 --- a/src/devices/sound/multipcm.cpp +++ b/src/devices/sound/multipcm.cpp @@ -575,23 +575,23 @@ void multipcm_device::device_start() save_item(NAME(m_address)); // Slots - m_slots = make_unique_clear<slot_t[]>(28); + m_slots = make_unique_clear<slot_t []>(28); + + save_pointer(STRUCT_MEMBER(m_slots, m_regs), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_playing), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_base), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_offset), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_step), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_pan), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_total_level), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_dest_total_level), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_total_level_step), 28); + save_pointer(STRUCT_MEMBER(m_slots, m_prev_sample), 28); + for (int32_t slot = 0; slot < 28; ++slot) { - m_slots[slot].m_slot_index = slot; m_slots[slot].m_playing = false; - save_item(NAME(m_slots[slot].m_slot_index), slot); - save_item(NAME(m_slots[slot].m_regs), slot); - save_item(NAME(m_slots[slot].m_playing), slot); - save_item(NAME(m_slots[slot].m_base), slot); - save_item(NAME(m_slots[slot].m_offset), slot); - save_item(NAME(m_slots[slot].m_step), slot); - save_item(NAME(m_slots[slot].m_pan), slot); - save_item(NAME(m_slots[slot].m_total_level), slot); - save_item(NAME(m_slots[slot].m_dest_total_level), slot); - save_item(NAME(m_slots[slot].m_total_level_step), slot); - save_item(NAME(m_slots[slot].m_prev_sample), slot); save_item(NAME(m_slots[slot].m_envelope_gen.m_volume), slot); save_item(NAME(m_slots[slot].m_envelope_gen.m_state), slot); save_item(NAME(m_slots[slot].m_envelope_gen.step), slot); diff --git a/src/devices/sound/multipcm.h b/src/devices/sound/multipcm.h index 626f4c99670..08d1e8d2fcf 100644 --- a/src/devices/sound/multipcm.h +++ b/src/devices/sound/multipcm.h @@ -79,7 +79,6 @@ private: struct slot_t { - uint8_t m_slot_index; uint8_t m_regs[8]; bool m_playing; sample_t m_sample; diff --git a/src/emu/device.h b/src/emu/device.h index 11798068259..b09bf535ed4 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -627,6 +627,12 @@ public: assert(m_save); m_save->save_pointer(this, name(), tag(), index, std::forward<ItemType>(value), valname, count); } + template<typename ItemType, typename ElementType> + void ATTR_COLD save_pointer(ItemType &&value, ElementType save_manager::pointer_unwrap<ItemType>::underlying_type::*element, const char *valname, u32 count, int index = 0) + { + assert(m_save); + m_save->save_pointer(this, name(), tag(), index, std::forward<ItemType>(value), element, valname, count); + } // debugging device_debug *debug() const { return m_debug.get(); } diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index f04854ee090..842f52b10ab 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -410,9 +410,13 @@ void device_execute_interface::interface_post_start() device().save_item(NAME(m_totalcycles)); device().save_item(NAME(m_localtime)); + // it's more efficient and causes less clutter to save these this way + device().save_item(STRUCT_MEMBER(m_input, m_stored_vector)); + device().save_item(STRUCT_MEMBER(m_input, m_curvector)); + // fill in the input states and IRQ callback information for (int line = 0; line < ARRAY_LENGTH(m_input); line++) - m_input[line].start(this, line); + m_input[line].start(*this, line); } @@ -668,17 +672,12 @@ device_execute_interface::device_input::device_input() // can set ourselves up //------------------------------------------------- -void device_execute_interface::device_input::start(device_execute_interface *execute, int linenum) +void device_execute_interface::device_input::start(device_execute_interface &execute, int linenum) { - m_execute = execute; + m_execute = &execute; m_linenum = linenum; reset(); - - device_t &device = m_execute->device(); - device.save_item(NAME(m_stored_vector), m_linenum); - device.save_item(NAME(m_curvector), m_linenum); - device.save_item(NAME(m_curstate), m_linenum); } diff --git a/src/emu/diexec.h b/src/emu/diexec.h index c4a99c63043..8745b15ae03 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -247,12 +247,12 @@ private: // internal information about the state of inputs class device_input { - static const int USE_STORED_VECTOR = 0xff000000; + static constexpr int USE_STORED_VECTOR = 0xff000000; public: device_input(); - void start(device_execute_interface *execute, int linenum); + void start(device_execute_interface &execute, int linenum); void reset(); void set_state_synced(int state, int vector = USE_STORED_VECTOR); diff --git a/src/emu/save.h b/src/emu/save.h index 5fe6c143c4b..631fd590296 100644 --- a/src/emu/save.h +++ b/src/emu/save.h @@ -19,7 +19,10 @@ #include <array> #include <cassert> +#include <memory> +#include <string> #include <type_traits> +#include <vector> @@ -60,7 +63,7 @@ typedef named_delegate<void ()> save_prepost_delegate; template <> inline void save_manager::save_item(device_t *device, const char *module, const char *tag, int index, std::vector<TYPE> &value, const char *name) { save_memory(device, module, tag, index, name, &value[0], sizeof(TYPE), value.size()); } // use this for saving members of structures in arrays -#define STRUCT_MEMBER(s, m) s, &save_manager::array_unwrap<std::remove_reference_t<decltype(s)> >::underlying_type::m, #s "." #m +#define STRUCT_MEMBER(s, m) s, &save_manager::pointer_unwrap<decltype(s)>::underlying_type::m, #s "." #m //************************************************************************** @@ -74,7 +77,7 @@ class save_manager { // type_checker is a set of templates to identify valid save types template <typename ItemType> struct type_checker { static constexpr bool is_atom = false; static constexpr bool is_pointer = false; }; - template <typename ItemType> struct type_checker<ItemType*> { static constexpr bool is_atom = false; static constexpr bool is_pointer = true; }; + template <typename ItemType> struct type_checker<ItemType *> { static constexpr bool is_atom = false; static constexpr bool is_pointer = true; }; class state_entry { @@ -110,7 +113,7 @@ public: static constexpr std::size_t SIZE = sizeof(underlying_type); static underlying_type *ptr(T &value) { return &value; } }; - template <typename T, std::size_t N> struct array_unwrap<T[N]> + template <typename T, std::size_t N> struct array_unwrap<T [N]> { using underlying_type = typename array_unwrap<T>::underlying_type; static constexpr std::size_t SAVE_COUNT = N * array_unwrap<T>::SAVE_COUNT; @@ -125,6 +128,12 @@ public: static underlying_type *ptr(std::array<T, N> &value) { return array_unwrap<T>::ptr(value[0]); } }; + // stuff to allow STRUCT_MEMBER to work with pointers + template <typename T> struct pointer_unwrap { using underlying_type = typename array_unwrap<T>::underlying_type; }; + template <typename T> struct pointer_unwrap<T &> { using underlying_type = typename pointer_unwrap<std::remove_cv_t<T> >::underlying_type; }; + template <typename T> struct pointer_unwrap<T *> { using underlying_type = typename array_unwrap<T>::underlying_type; }; + template <typename T> struct pointer_unwrap<std::unique_ptr<T []> > { using underlying_type = typename array_unwrap<T>::underlying_type; }; + // construction/destruction save_manager(running_machine &machine); |