summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/emu/attotime.cpp17
-rw-r--r--src/emu/attotime.h2
-rw-r--r--src/emu/emufwd.h3
-rw-r--r--src/emu/save.h111
4 files changed, 99 insertions, 34 deletions
diff --git a/src/emu/attotime.cpp b/src/emu/attotime.cpp
index a1ba4d9ed61..3ba52c3157a 100644
--- a/src/emu/attotime.cpp
+++ b/src/emu/attotime.cpp
@@ -8,9 +8,8 @@
***************************************************************************/
-#include "emucore.h"
-#include "eminline.h"
-#include "attotime.h"
+#include "emu.h"
+
//**************************************************************************
// GLOBAL VARIABLES
@@ -170,3 +169,15 @@ std::string attotime::to_string() const
int nsec = t.attoseconds() / ATTOSECONDS_PER_NANOSECOND;
return util::string_format("%s%04d.%03d,%03d,%03d", sign, int(t.seconds()), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
}
+
+
+//-------------------------------------------------
+// register_save - register for save states
+//-------------------------------------------------
+
+void attotime::register_save(save_registrar &save)
+{
+ // use names without m_ prefix for backwards compatibility
+ save.reg(m_attoseconds, "attoseconds");
+ save.reg(m_seconds, "seconds");
+}
diff --git a/src/emu/attotime.h b/src/emu/attotime.h
index c975bbde0d3..d17a5227967 100644
--- a/src/emu/attotime.h
+++ b/src/emu/attotime.h
@@ -164,6 +164,8 @@ public:
attotime &operator*=(u32 factor);
attotime &operator/=(u32 factor);
+ void register_save(save_registrar &save);
+
// members
seconds_t m_seconds;
attoseconds_t m_attoseconds;
diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h
index b3969a8fc99..171b9f7c5fa 100644
--- a/src/emu/emufwd.h
+++ b/src/emu/emufwd.h
@@ -210,6 +210,9 @@ class rom_entry;
// declared in romload.h
class rom_load_manager;
+// declared in save.h
+class save_registrar;
+
// declared in schedule.h
class device_scheduler;
class emu_timer;
diff --git a/src/emu/save.h b/src/emu/save.h
index cfd674e738e..71e6679a36e 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -70,9 +70,43 @@ typedef named_delegate<void ()> save_prepost_delegate;
// TYPE DEFINITIONS
//**************************************************************************
+class save_manager;
class ram_state;
class rewinder;
+// helper class to provide pass-through interface for saving struct items
+class save_registrar
+{
+ friend class save_manager;
+
+public:
+ save_registrar(save_manager &manager, device_t *device, char const *module, char const *tag, int index, char const *valname) :
+ m_manager(manager),
+ m_device(device),
+ m_module(module),
+ m_tag(tag),
+ m_valname(valname),
+ m_inner_index(index),
+ m_outer_index(-1)
+ {
+ }
+
+ template <typename ItemType>
+ void reg(ItemType &value, const char *valname);
+
+ template <typename ItemType>
+ void reg(ItemType &value, const char *valname, int index);
+
+private:
+ save_manager &m_manager;
+ device_t *m_device;
+ char const *m_module;
+ char const *m_tag;
+ char const *m_valname;
+ int m_inner_index;
+ int m_outer_index;
+};
+
class save_manager
{
// stuff for working with arrays
@@ -102,6 +136,13 @@ class save_manager
template <typename ItemType> struct is_atom : public std::false_type { };
template <typename ItemType> struct is_vector_safe : public std::false_type { };
+ // template to query if a type is a struct/union that can be saved; note that bitmap_t is explicitly
+ // excluded because it is handled as a special case
+ template <typename ItemType> struct is_saveable_struct
+ {
+ static constexpr bool value = (std::is_class<ItemType>::value || std::is_union<ItemType>::value) && !std::is_base_of<bitmap_t, ItemType>::value && !is_atom<ItemType>::value;
+ };
+
class state_entry
{
public:
@@ -166,6 +207,23 @@ public:
save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT);
}
+ // templatized wrappers for saving saveable structs
+ template<typename ItemType>
+ std::enable_if_t<is_saveable_struct<typename array_unwrap<ItemType>::underlying_type>::value && array_unwrap<ItemType>::SAVE_COUNT == 1>
+ save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname)
+ {
+ save_registrar save(*this, device, module, tag, index, valname);
+ value.register_save(save);
+ }
+ template<typename ItemType>
+ std::enable_if_t<is_saveable_struct<typename array_unwrap<ItemType>::underlying_type>::value && array_unwrap<ItemType>::SAVE_COUNT != 1>
+ save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname)
+ {
+ save_registrar save(*this, device, module, tag, index, valname);
+ for (save.m_outer_index = 0; save.m_outer_index < array_unwrap<ItemType>::SAVE_COUNT; save.m_outer_index++)
+ array_unwrap<ItemType>::ptr(value)[save.m_outer_index].register_save(save);
+ }
+
// 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)
@@ -236,37 +294,6 @@ public:
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)
@@ -377,6 +404,28 @@ public:
};
+template <typename ItemType>
+void save_registrar::reg(ItemType &value, const char *valname)
+{
+ std::string fullname;
+ if (m_outer_index == -1)
+ fullname = string_format("%s.%s", m_valname, valname);
+ else
+ fullname = string_format("%s[%d].%s", m_valname, m_outer_index, valname);
+ m_manager.save_item(m_device, m_module, m_tag, m_inner_index, value, fullname.c_str());
+}
+
+template <typename ItemType>
+void save_registrar::reg(ItemType &value, const char *valname, int index)
+{
+ std::string fullname;
+ if (m_outer_index == -1)
+ fullname = string_format("%s.%s[%d]", m_valname, valname, index);
+ else
+ fullname = string_format("%s[%d].%s[%d]", m_valname, m_outer_index, valname, index);
+ m_manager.save_item(m_device, m_module, m_tag, m_inner_index, value, fullname.c_str());
+}
+
// 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