/*************************************************************************** state.h Save state management functions. Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. ***************************************************************************/ #pragma once #ifndef __STATE_H__ #define __STATE_H__ #include "mamecore.h" /*************************************************************************** TYPE DEFINTIONS ***************************************************************************/ typedef void (*state_presave_func)(running_machine *machine, void *param); typedef void (*state_postload_func)(running_machine *machine, void *param); /*************************************************************************** CONSTANTS ***************************************************************************/ enum _state_save_error { STATERR_NONE, STATERR_ILLEGAL_REGISTRATIONS, STATERR_INVALID_HEADER, STATERR_READ_ERROR, STATERR_WRITE_ERROR }; typedef enum _state_save_error state_save_error; /*************************************************************************** MACROS ***************************************************************************/ #define STATE_PRESAVE(name) void name(running_machine *machine, void *param) #define STATE_POSTLOAD(name) void name(running_machine *machine, void *param) #define IS_COMPATIBLE_TYPE(_valtype, _checktype) \ (sizeof(_valtype) == sizeof(_checktype) && TYPES_COMPATIBLE(_valtype, _checktype)) #define IS_VALID_SAVE_TYPE(_valtype) \ (IS_COMPATIBLE_TYPE(_valtype, double) || IS_COMPATIBLE_TYPE(_valtype, float) || \ IS_COMPATIBLE_TYPE(_valtype, INT64) || IS_COMPATIBLE_TYPE(_valtype, UINT64) || \ IS_COMPATIBLE_TYPE(_valtype, INT32) || IS_COMPATIBLE_TYPE(_valtype, UINT32) || \ IS_COMPATIBLE_TYPE(_valtype, INT16) || IS_COMPATIBLE_TYPE(_valtype, UINT16) || \ IS_COMPATIBLE_TYPE(_valtype, INT8) || IS_COMPATIBLE_TYPE(_valtype, UINT8) || \ IS_COMPATIBLE_TYPE(_valtype, PAIR) || IS_COMPATIBLE_TYPE(_valtype, PAIR64)) /* generic registration; all further registrations are based on this */ #define state_save_register_generic(_mach, _mod, _tag, _index, _name, _val, _valsize, _count) \ do { \ assert_always(IS_VALID_SAVE_TYPE(_valsize), "Invalid data type supplied for state saving."); \ state_save_register_memory(_mach, _mod, _tag, _index, _name, _val, sizeof(_valsize), _count); \ } while (0) /* register items with explicit tags */ #define state_save_register_item(_mach, _mod, _tag, _index, _val) \ state_save_register_generic(_mach, _mod, _tag, _index, #_val, &_val, _val, 1) #define state_save_register_item_pointer(_mach, _mod, _tag, _index, _val, _count) \ state_save_register_generic(_mach, _mod, _tag, _index, #_val, &_val[0], _val[0], _count) #define state_save_register_item_array(_mach, _mod, _tag, _index, _val) \ state_save_register_item_pointer(_mach, _mod, _tag, _index, _val, sizeof(_val)/sizeof(_val[0])) #define state_save_register_item_2d_array(_mach, _mod, _tag, _index, _val) \ state_save_register_item_pointer(_mach, _mod, _tag, _index, _val[0], sizeof(_val)/sizeof(_val[0][0])) #define state_save_register_item_bitmap(_mach, _mod, _tag, _index, _val) \ state_save_register_bitmap(_mach, _mod, _tag, _index, #_val, _val) /* register device items */ #define state_save_register_device_item(_dev, _index, _val) \ state_save_register_generic((_dev)->machine, device_get_name(_dev), (_dev)->tag, _index, #_val, &_val, _val, 1) #define state_save_register_device_item_pointer(_dev, _index, _val, _count) \ state_save_register_generic((_dev)->machine, device_get_name(_dev), (_dev)->tag, _index, #_val, &_val[0], _val[0], _count) #define state_save_register_device_item_array(_dev, _index, _val) \ state_save_register_item_pointer((_dev)->machine, device_get_name(_dev), (_dev)->tag, _index, _val, sizeof(_val)/sizeof(_val[0])) #define state_save_register_device_item_2d_array(_dev, _index, _val) \ state_save_register_item_pointer((_dev)->machine, device_get_name(_dev), (_dev)->tag, _index, _val[0], sizeof(_val)/sizeof(_val[0][0])) #define state_save_register_device_item_bitmap(_dev, _index, _val) \ state_save_register_bitmap((_dev)->machine, device_get_name(_dev), (_dev)->tag, _index, #_val, _val) /* register global items */ #define state_save_register_global(_mach, _val) \ state_save_register_item(_mach, "globals", NULL, 0, _val) #define state_save_register_global_pointer(_mach, _val, _count) \ state_save_register_item_pointer(_mach, "globals", NULL, 0, _val, _count) #define state_save_register_global_array(_mach, _val) \ state_save_register_item_array(_mach, "globals", NULL, 0, _val) #define state_save_register_global_2d_array(_mach, _val) \ state_save_register_item_2d_array(_mach, "globals", NULL, 0, _val) #define state_save_register_global_bitmap(_mach, _val) \ state_save_register_bitmap(_mach, "globals", NULL, 0, #_val, _val) /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ /* ----- core system operations ----- */ /* initialize the system and reset all registrations */ void state_init(running_machine *machine); /* return the number of total registrations so far */ int state_save_get_reg_count(running_machine *machine); /* ----- registration handling ----- */ /* allow/disallow registrations to happen (called by the core) */ void state_save_allow_registration(running_machine *machine, int allowed); /* query whether or not registrations are allowed */ int state_save_registration_allowed(running_machine *machine); /* register an array of data in memory */ void state_save_register_memory(running_machine *machine, const char *module, const char *tag, UINT32 index, const char *name, void *val, UINT32 valsize, UINT32 valcount); /* register a bitmap to be saved */ void state_save_register_bitmap(running_machine *machine, const char *module, const char *tag, UINT32 index, const char *name, bitmap_t *val); /* ----- callback function registraton ----- */ /* register a pre-save function callback */ void state_save_register_presave(running_machine *machine, state_presave_func func, void *param); /* register a post-load function callback */ void state_save_register_postload(running_machine *machine, state_postload_func func, void *param); /* ----- registration freeing ----- */ /* free all registrations that have been tagged with the current resource tag */ void state_destructor(void *ptr, size_t size); /* ----- save state file processing ----- */ /* check if a file is a valid save state */ state_save_error state_save_check_file(running_machine *machine, mame_file *file, const char *gamename, void (CLIB_DECL *errormsg)(const char *fmt, ...)); /* write out the save state file */ state_save_error state_save_write_file(running_machine *machine, mame_file *file); /* read in a save state file */ state_save_error state_save_read_file(running_machine *machine, mame_file *file); /* ----- debugging ----- */ /* return an item with the given index */ const char *state_save_get_indexed_item(running_machine *machine, int index, void **base, UINT32 *valsize, UINT32 *valcount); /* dump the registry to the logfile */ void state_save_dump_registry(running_machine *machine); #endif /* __STATE_H__ */