1 #ifndef _STATE_H
2 #define _STATE_H
3 
4 #include <retro_inline.h>
5 
6 typedef struct
7 {
8    uint8_t *data;
9    uint32_t loc;
10    uint32_t len;
11    uint32_t malloced;
12    uint32_t initial_malloc; // A setting!
13 } StateMem;
14 
15 // Eh, we abuse the smem_* in-memory stream code
16 // in a few other places. :)
17 int32_t smem_read(StateMem *st, void *buffer, uint32_t len);
18 int32_t smem_write(StateMem *st, void *buffer, uint32_t len);
19 int32_t smem_putc(StateMem *st, int value);
20 int32_t smem_seek(StateMem *st, uint32_t offset, int whence);
21 int smem_write32le(StateMem *st, uint32_t b);
22 int smem_read32le(StateMem *st, uint32_t *b);
23 
24 int MDFNSS_SaveSM(void *st, int, int, const void*, const void*, const void*);
25 int MDFNSS_LoadSM(void *st, int, int);
26 
27 // Flag for a single, >= 1 byte native-endian variable
28 #define MDFNSTATE_RLSB            0x80000000
29 
30 // 32-bit native-endian elements
31 #define MDFNSTATE_RLSB32          0x40000000
32 
33 // 16-bit native-endian elements
34 #define MDFNSTATE_RLSB16          0x20000000
35 
36 // 64-bit native-endian elements
37 #define MDFNSTATE_RLSB64          0x10000000
38 
39 #define MDFNSTATE_BOOL		  0x08000000
40 
41 typedef struct {
42    void *v;		// Pointer to the variable/array
43    uint32_t size;		// Length, in bytes, of the data to be saved EXCEPT:
44    //  In the case of MDFNSTATE_BOOL, it is the number of bool elements to save(bool is not always 1-byte).
45    // If 0, the subchunk isn't saved.
46    uint32_t flags;	// Flags
47    const char *name;	// Name
48 } SFORMAT;
49 
SF_IS_BOOL(bool *)50 INLINE bool SF_IS_BOOL(bool *) { return(1); }
SF_IS_BOOL(void *)51 INLINE bool SF_IS_BOOL(void *) { return(0); }
52 
SF_FORCE_AB(bool *)53 INLINE uint32_t SF_FORCE_AB(bool *) { return(0); }
54 
SF_FORCE_A8(int8_t *)55 INLINE uint32_t SF_FORCE_A8(int8_t *) { return(0); }
SF_FORCE_A8(uint8_t *)56 INLINE uint32_t SF_FORCE_A8(uint8_t *) { return(0); }
57 
SF_FORCE_A16(int16_t *)58 INLINE uint32_t SF_FORCE_A16(int16_t *) { return(0); }
SF_FORCE_A16(uint16_t *)59 INLINE uint32_t SF_FORCE_A16(uint16_t *) { return(0); }
60 
SF_FORCE_A32(int32_t *)61 INLINE uint32_t SF_FORCE_A32(int32_t *) { return(0); }
SF_FORCE_A32(uint32_t *)62 INLINE uint32_t SF_FORCE_A32(uint32_t *) { return(0); }
63 
SF_FORCE_A64(int64_t *)64 INLINE uint32_t SF_FORCE_A64(int64_t *) { return(0); }
SF_FORCE_A64(uint64_t *)65 INLINE uint32_t SF_FORCE_A64(uint64_t *) { return(0); }
66 
SF_FORCE_D(double *)67 INLINE uint32_t SF_FORCE_D(double *) { return(0); }
68 
69 #define SFVARN(x, n) { &(x), SF_IS_BOOL(&(x)) ? 1 : (uint32_t)sizeof(x), MDFNSTATE_RLSB | (SF_IS_BOOL(&(x)) ? MDFNSTATE_BOOL : 0), n }
70 #define SFVAR(x) SFVARN((x), #x)
71 
72 #define SFARRAYN(x, l, n) { (x), (uint32_t)(l), 0 | SF_FORCE_A8(x), n }
73 #define SFARRAY(x, l) SFARRAYN((x), (l), #x)
74 
75 #define SFARRAYBN(x, l, n) { (x), (uint32_t)(l), MDFNSTATE_BOOL | SF_FORCE_AB(x), n }
76 #define SFARRAYB(x, l) SFARRAYBN((x), (l), #x)
77 
78 #define SFARRAY16N(x, l, n) { (x), (uint32_t)((l) * sizeof(uint16_t)), MDFNSTATE_RLSB16 | SF_FORCE_A16(x), n }
79 #define SFARRAY16(x, l) SFARRAY16N((x), (l), #x)
80 
81 #define SFARRAY32N(x, l, n) { (x), (uint32_t)((l) * sizeof(uint32_t)), MDFNSTATE_RLSB32 | SF_FORCE_A32(x), n }
82 #define SFARRAY32(x, l) SFARRAY32N((x), (l), #x)
83 
84 #define SFARRAY64N(x, l, n) { (x), (uint32_t)((l) * sizeof(uint64_t)), MDFNSTATE_RLSB64 | SF_FORCE_A64(x), n }
85 #define SFARRAY64(x, l) SFARRAY64N((x), (l), #x)
86 
87 #define SFARRAYDN(x, l, n) { (x), (uint32_t)((l) * 8), MDFNSTATE_RLSB64 | SF_FORCE_D(x), n }
88 #define SFARRAYD(x, l) SFARRAYDN((x), (l), #x)
89 
90 #define SFEND { 0, 0, 0, 0 }
91 
92 #include <vector>
93 
94 // State-Section Descriptor
95 class SSDescriptor
96 {
97    public:
98       SSDescriptor(SFORMAT *n_sf, const char *n_name, bool n_optional = 0)
99       {
100          sf = n_sf;
101          name = n_name;
102          optional = n_optional;
103       }
~SSDescriptor(void)104       ~SSDescriptor(void)
105       {
106 
107       }
108 
109       SFORMAT *sf;
110       const char *name;
111       bool optional;
112 };
113 
114 int MDFNSS_StateAction(void *st, int load, int data_only, std::vector <SSDescriptor> &sections);
115 int MDFNSS_StateAction(void *st, int load, int data_only, SFORMAT *sf, const char *name, bool optional = 0);
116 
117 #endif
118