summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/save.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/save.h')
-rw-r--r--src/emu/save.h198
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 &reg(std::unique_ptr<T> &data, char const *name)
+ std::enable_if_t<!std::is_array<T>::value, save_registrar> &reg(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 &reg(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 &reg(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 &reg(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