[wrap]
/***************************************************************************
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(typeof(_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__ */