diff options
Diffstat (limited to 'src/emu/save.h')
| -rw-r--r-- | src/emu/save.h | 198 |
1 files changed, 15 insertions, 183 deletions
diff --git a/src/emu/save.h b/src/emu/save.h index 892c6e6ce89..bf2654acc84 100644 --- a/src/emu/save.h +++ b/src/emu/save.h @@ -77,19 +77,10 @@ typedef named_delegate<void ()> save_prepost_delegate; template<> struct save_registrar::is_floating_point_like<Type> { static constexpr bool value = true; }; -// use this to declare a given type is a simple, non-pointer type that can be -// saved; in general, this is intended only to be used for specific enum types -// defined by your device -#define ALLOW_SAVE_TYPE(TYPE) \ - template <> struct save_manager::is_atom<TYPE> { static constexpr bool value = true; }; -// use this as above, but also to declare that std::vector<TYPE> is safe as well -#define ALLOW_SAVE_TYPE_AND_VECTOR(TYPE) \ - ALLOW_SAVE_TYPE(TYPE) \ - template <> struct save_manager::is_vector_safe<TYPE> { static constexpr bool value = true; }; - -// use this for saving members of structures in arrays -#define STRUCT_MEMBER(s, m) s, &save_manager::pointer_unwrap<decltype(s)>::underlying_type::m, #s "." #m +// remove me +#define ALLOW_SAVE_TYPE(TYPE) +#define ALLOW_SAVE_TYPE_AND_VECTOR(TYPE) //************************************************************************** @@ -272,7 +263,7 @@ public: // std::unique_ptrs -- these are containers with a single "unique" item within template<typename T> - save_registrar ®(std::unique_ptr<T> &data, char const *name) + std::enable_if_t<!std::is_array<T>::value, save_registrar> ®(std::unique_ptr<T> &data, char const *name) { if (data.get() == nullptr) throw emu_fatalerror("Passed null pointer to save state registration."); @@ -287,16 +278,16 @@ public: template<typename T, std::size_t N> save_registrar ®(T (&data)[N], char const *name) { - save_registrar container(*this, save_registered_item::save_type(N), sizeof(data[0]), name, &data[0]); + save_registrar container(*this, save_registered_item::save_type(N), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]); container.reg(data[0], ""); return *this; } - // std::arrays -- these identically to arrays + // std::arrays -- treat these identically to arrays template<typename T, std::size_t N> save_registrar ®(std::array<T, N> &data, char const *name) { - save_registrar container(*this, save_registered_item::save_type(N), sizeof(data[0]), name, &data[0]); + save_registrar container(*this, save_registered_item::save_type(N), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]); container.reg(data[0], ""); return *this; } @@ -308,7 +299,7 @@ public: if (data == nullptr) throw emu_fatalerror("Passed null pointer to save state registration."); - save_registrar container(*this, save_registered_item::save_type(count), sizeof(data[0]), name, &data[0]); + save_registrar container(*this, save_registered_item::save_type(count), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]); container.reg(data[0], ""); return *this; } @@ -325,7 +316,7 @@ public: save_registrar container(*this, save_registered_item::TYPE_VECTOR, sizeof(data), "", &data, &data[0]); // then an array container within - save_registrar subcontainer(container, save_registered_item::save_type(data.size()), sizeof(data[0]), name, &data[0]); + save_registrar subcontainer(container, save_registered_item::save_type(data.size()), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]); subcontainer.reg(data[0], ""); return *this; } @@ -334,12 +325,16 @@ public: template<typename T> save_registrar ®(std::unique_ptr<T[]> &data, char const *name, std::size_t count) { + // skip if nothing + if (count == 0) + return *this; + if (data.get() == nullptr) throw emu_fatalerror("Passed null pointer to save state registration."); - save_registrar container(*this, save_registered_item::TYPE_UNIQUE, sizeof(data), "", &data, &data[0]); + save_registrar container(*this, save_registered_item::TYPE_UNIQUE, sizeof(data), "", &data, data.get()); - save_registrar subcontainer(container, save_registered_item::save_type(count), sizeof(data[0]), name, &data[0]); + save_registrar subcontainer(container, save_registered_item::save_type(count), uintptr_t(&data[1]) - uintptr_t(&data[0]), name, &data[0]); subcontainer.reg(data[0], ""); return *this; } @@ -461,12 +456,6 @@ class save_manager friend class rewinder; public: - // 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); @@ -488,132 +477,6 @@ public: void dispatch_presave(); void dispatch_postload(); - // generic memory registration - void save_memory(device_t *device, const char *module, const char *tag, u32 index, const char *name, void *val, u32 valsize, u32 valcount = 1, u32 blockcount = 1, u32 stride = 0); - - // templatized wrapper for general objects and arrays - template <typename ItemType> - std::enable_if_t<is_atom<typename array_unwrap<ItemType>::underlying_type>::value> save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) - { - static_assert(!std::is_pointer<ItemType>::value, "Called save_item on a pointer with no count!"); - save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT); - } - - // templatized wrapper for structure members - template <typename ItemType, typename StructType, typename ElementType> - void save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, ElementType StructType::*element, const char *valname) - { - static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_item on a non-matching struct member pointer!"); - static_assert(!std::is_pointer<ElementType>::value, "Called save_item on a struct member pointer!"); - static_assert(is_atom<typename array_unwrap<ElementType>::underlying_type>::value, "Called save_item on a non-fundamental type!"); - save_memory(device, module, tag, index, valname, array_unwrap<ElementType>::ptr(array_unwrap<ItemType>::ptr(value)->*element), array_unwrap<ElementType>::SIZE, array_unwrap<ElementType>::SAVE_COUNT, array_unwrap<ItemType>::SAVE_COUNT, sizeof(typename array_unwrap<ItemType>::underlying_type)); - } - - // templatized wrapper for pointers - template <typename ItemType> - std::enable_if_t<is_atom<typename array_unwrap<ItemType>::underlying_type>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, const char *valname, u32 count) - { - save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value[0]), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT * count); - } - - template <typename ItemType, typename StructType, typename ElementType> - void save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, ElementType StructType::*element, const char *valname, u32 count) - { - static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-matching struct member pointer!"); - static_assert(!std::is_pointer<ElementType>::value, "Called save_pointer on a struct member pointer!"); - static_assert(is_atom<typename array_unwrap<ElementType>::underlying_type>::value, "Called save_pointer on a non-fundamental type!"); - save_memory(device, module, tag, index, valname, array_unwrap<ElementType>::ptr(array_unwrap<ItemType>::ptr(value[0])->*element), array_unwrap<ElementType>::SIZE, array_unwrap<ElementType>::SAVE_COUNT, array_unwrap<ItemType>::SAVE_COUNT * count, sizeof(typename array_unwrap<ItemType>::underlying_type)); - } - - // templatized wrapper for std::unique_ptr - template <typename ItemType> - std::enable_if_t<is_atom<typename array_unwrap<ItemType>::underlying_type>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, const char *valname, u32 count) - { - save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value[0]), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT * count); - } - - template <typename ItemType, typename StructType, typename ElementType> - void save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, ElementType StructType::*element, const char *valname, u32 count) - { - static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-matching struct member pointer!"); - static_assert(!std::is_pointer<ElementType>::value, "Called save_pointer on a struct member pointer!"); - static_assert(is_atom<typename array_unwrap<ElementType>::underlying_type>::value, "Called save_pointer on a non-fundamental type!"); - save_memory(device, module, tag, index, valname, array_unwrap<ElementType>::ptr(array_unwrap<ItemType>::ptr(value[0])->*element), array_unwrap<ElementType>::SIZE, array_unwrap<ElementType>::SAVE_COUNT, array_unwrap<ItemType>::SAVE_COUNT * count, sizeof(typename array_unwrap<ItemType>::underlying_type)); - } - - // templatized wrapper for std::vector - template <typename ItemType> - std::enable_if_t<is_vector_safe<typename array_unwrap<ItemType>::underlying_type>::value> save_item(device_t *device, const char *module, const char *tag, int index, std::vector<ItemType> &value, const char *valname) - { - save_pointer(device, module, tag, index, &value[0], valname, value.size()); - } - - // specializations for bitmaps - void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind8 &value, const char *valname) - { - save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); - } - - void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind16 &value, const char *valname) - { - save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); - } - - void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_ind32 &value, const char *valname) - { - save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); - } - - void save_item(device_t *device, const char *module, const char *tag, int index, bitmap_rgb32 &value, const char *valname) - { - save_memory(device, module, tag, index, valname, &value.pix(0), value.bpp() / 8, value.rowpixels() * value.height()); - } - - // specializations for attotimes - template <typename ItemType> - std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, attotime>::value> save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname) - { - std::string tempstr; - tempstr.assign(valname).append(".attoseconds"); - save_item(device, module, tag, index, value, &attotime::m_attoseconds, tempstr.c_str()); - tempstr.assign(valname).append(".seconds"); - save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str()); - } - - template <typename ItemType> - std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, attotime>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, const char *valname, u32 count) - { - std::string tempstr; - tempstr.assign(valname).append(".attoseconds"); - save_item(device, module, tag, index, value, &attotime::m_attoseconds, tempstr.c_str(), count); - tempstr.assign(valname).append(".seconds"); - save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str(), count); - } - - template <typename ItemType> - std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, attotime>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, const char *valname, u32 count) - { - std::string tempstr; - tempstr.assign(valname).append(".attoseconds"); - save_item(device, module, tag, index, value, &attotime::m_attoseconds, tempstr.c_str(), count); - tempstr.assign(valname).append(".seconds"); - save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str(), count); - } - - // global memory registration - template <typename ItemType> - void save_item(ItemType &value, const char *valname, int index = 0) - { save_item(nullptr, "global", nullptr, index, value, valname); } - template <typename ItemType, typename StructType, typename ElementType> - void save_item(ItemType &value, ElementType StructType::*element, const char *valname, int index = 0) - { save_item(nullptr, "global", nullptr, index, value, element, valname); } - template <typename ItemType> - void save_pointer(ItemType &&value, const char *valname, u32 count, int index = 0) - { save_pointer(nullptr, "global", nullptr, index, std::forward<ItemType>(value), valname, count); } - template <typename ItemType, typename StructType, typename ElementType> - void save_pointer(ItemType &&value, ElementType StructType::*element, const char *valname, u32 count, int index = 0) - { save_pointer(nullptr, "global", nullptr, index, std::forward<ItemType>(value), element, valname, count); } - // file processing static save_error check_file(running_machine &machine, emu_file &file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...)); save_error write_file(emu_file &file); @@ -626,7 +489,6 @@ public: save_error read_buffer(const void *buf, size_t size); save_registrar &root_registrar() { return m_root_registrar; } - save_registrar &legacy_registrar() { return m_legacy_registrar; } void test_dump(); private: @@ -657,7 +519,6 @@ private: save_registered_item m_root_item; save_registrar m_root_registrar; - save_registrar m_legacy_registrar; std::vector<std::unique_ptr<state_entry>> m_entry_list; // list of registered entries std::vector<std::unique_ptr<ram_state>> m_ramstate_list; // list of ram states @@ -717,33 +578,4 @@ public: bool step(); }; - -// template specializations to enumerate the fundamental atomic types you are allowed to save -ALLOW_SAVE_TYPE_AND_VECTOR(char) -ALLOW_SAVE_TYPE (bool) // std::vector<bool> may be packed internally -ALLOW_SAVE_TYPE_AND_VECTOR(osd::s8) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::u8) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::s16) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::u16) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::s32) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::u32) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::s64) -ALLOW_SAVE_TYPE_AND_VECTOR(osd::u64) -ALLOW_SAVE_TYPE_AND_VECTOR(PAIR) -ALLOW_SAVE_TYPE_AND_VECTOR(PAIR64) -ALLOW_SAVE_TYPE_AND_VECTOR(float) -ALLOW_SAVE_TYPE_AND_VECTOR(double) -ALLOW_SAVE_TYPE_AND_VECTOR(endianness_t) -ALLOW_SAVE_TYPE_AND_VECTOR(rgb_t) - - - - - - - - - - - #endif // MAME_EMU_SAVE_H |
