annotate serialize.c @ 1971:80920c21bb52

Add an event log soft flush and call it twice per frame in between hard flushes to netplay latency when there are insufficient hardware updates to flush packets in the middle of a frame
author Michael Pavone <pavone@retrodev.com>
date Fri, 08 May 2020 11:40:30 -0700
parents c3c62dbf1ceb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1427
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 #include <string.h>
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 #include <stdlib.h>
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 #include <stdio.h>
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 #include "serialize.h"
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5 #include "util.h"
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 #ifndef SERIALIZE_DEFAULT_SIZE
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 #define SERIALIZE_DEFAULT_SIZE (256*1024) //default to enough for a Genesis save state
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 #endif
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 void init_serialize(serialize_buffer *buf)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 buf->storage = SERIALIZE_DEFAULT_SIZE;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 buf->size = 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 buf->current_section_start = 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 buf->data = malloc(SERIALIZE_DEFAULT_SIZE);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20 static void reserve(serialize_buffer *buf, size_t amount)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 if (amount > (buf->storage - buf->size)) {
1946
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
23 if (amount < buf->storage) {
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
24 buf->storage *= 2;
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
25 } else {
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
26 //doublign isn't enough, increase by the precise amount needed
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
27 buf->storage += amount - (buf->storage - buf->size);
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
28 }
c3c62dbf1ceb WIP netplay support
Michael Pavone <pavone@retrodev.com>
parents: 1428
diff changeset
29 buf->data = realloc(buf->data, buf->storage + sizeof(*buf));
1427
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 void save_int32(serialize_buffer *buf, uint32_t val)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 reserve(buf, sizeof(val));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 buf->data[buf->size++] = val >> 24;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 buf->data[buf->size++] = val >> 16;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 buf->data[buf->size++] = val >> 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 buf->data[buf->size++] = val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 void save_int16(serialize_buffer *buf, uint16_t val)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 reserve(buf, sizeof(val));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 buf->data[buf->size++] = val >> 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 buf->data[buf->size++] = val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 void save_int8(serialize_buffer *buf, uint8_t val)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 reserve(buf, sizeof(val));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52 buf->data[buf->size++] = val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 void save_string(serialize_buffer *buf, char *val)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 size_t len = strlen(val);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 save_buffer8(buf, val, len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 void save_buffer8(serialize_buffer *buf, void *val, size_t len)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 reserve(buf, len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 memcpy(&buf->data[buf->size], val, len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 buf->size += len;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 void save_buffer16(serialize_buffer *buf, uint16_t *val, size_t len)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 reserve(buf, len * sizeof(*val));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 for(; len != 0; len--, val++) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 buf->data[buf->size++] = *val >> 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 buf->data[buf->size++] = *val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 void save_buffer32(serialize_buffer *buf, uint32_t *val, size_t len)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79 reserve(buf, len * sizeof(*val));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 for(; len != 0; len--, val++) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
81 buf->data[buf->size++] = *val >> 24;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 buf->data[buf->size++] = *val >> 16;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 buf->data[buf->size++] = *val >> 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 buf->data[buf->size++] = *val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
85 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
88 void start_section(serialize_buffer *buf, uint16_t section_id)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90 save_int16(buf, section_id);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 //reserve some space for size once we end this section
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 reserve(buf, sizeof(uint32_t));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93 buf->size += sizeof(uint32_t);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 //save start point for use in end_device
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 buf->current_section_start = buf->size;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98 void end_section(serialize_buffer *buf)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100 size_t section_size = buf->size - buf->current_section_start;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 if (section_size > 0xFFFFFFFFU) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 fatal_error("Sections larger than 4GB are not supported");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 uint32_t size = section_size;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 uint8_t *field = buf->data + buf->current_section_start - sizeof(uint32_t);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 *(field++) = size >> 24;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 *(field++) = size >> 16;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 *(field++) = size >> 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109 *(field++) = size;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 buf->current_section_start = 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 void register_section_handler(deserialize_buffer *buf, section_handler handler, uint16_t section_id)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115 if (section_id > buf->max_handler) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 uint16_t old_max = buf->max_handler;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 if (buf->max_handler < 0x8000) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
118 buf->max_handler *= 2;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119 } else {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
120 buf->max_handler = 0xFFFF;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
121 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
122 buf->handlers = realloc(buf->handlers, (buf->max_handler+1) * sizeof(handler));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
123 memset(buf->handlers + old_max + 1, 0, (buf->max_handler - old_max) * sizeof(handler));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
124 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
125 if (!buf->handlers) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 buf->handlers = calloc(buf->max_handler + 1, sizeof(handler));
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 buf->handlers[section_id] = handler;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 void init_deserialize(deserialize_buffer *buf, uint8_t *data, size_t size)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
133 buf->size = size;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 buf->cur_pos = 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
135 buf->data = data;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 buf->handlers = NULL;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137 buf->max_handler = 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
140 uint32_t load_int32(deserialize_buffer *buf)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 uint32_t val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 if ((buf->size - buf->cur_pos) < sizeof(val)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
144 fatal_error("Failed to load required int32 field");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
145 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
146 val = buf->data[buf->cur_pos++] << 24;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 val |= buf->data[buf->cur_pos++] << 16;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148 val |= buf->data[buf->cur_pos++] << 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 val |= buf->data[buf->cur_pos++];
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
150 return val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
152
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
153 uint16_t load_int16(deserialize_buffer *buf)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
154 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 uint16_t val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
156 if ((buf->size - buf->cur_pos) < sizeof(val)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
157 fatal_error("Failed to load required int16 field");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 val = buf->data[buf->cur_pos++] << 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 val |= buf->data[buf->cur_pos++];
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 return val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
163
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
164 uint8_t load_int8(deserialize_buffer *buf)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
166 uint8_t val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
167 if ((buf->size - buf->cur_pos) < sizeof(val)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
168 fatal_error("Failed to load required int8 field");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
169 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
170 val = buf->data[buf->cur_pos++];
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 return val;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 void load_buffer8(deserialize_buffer *buf, void *dst, size_t len)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 if ((buf->size - buf->cur_pos) < len) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
177 fatal_error("Failed to load required buffer of size %d", len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
179 memcpy(dst, buf->data + buf->cur_pos, len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
180 buf->cur_pos += len;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
181 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
182
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
183 void load_buffer16(deserialize_buffer *buf, uint16_t *dst, size_t len)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
184 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
185 if ((buf->size - buf->cur_pos) < len * sizeof(uint16_t)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186 fatal_error("Failed to load required buffer of size %d\n", len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
188 for(; len != 0; len--, dst++) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
189 uint16_t value = buf->data[buf->cur_pos++] << 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190 value |= buf->data[buf->cur_pos++];
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
191 *dst = value;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
192 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
193 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
194 void load_buffer32(deserialize_buffer *buf, uint32_t *dst, size_t len)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
195 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
196 if ((buf->size - buf->cur_pos) < len * sizeof(uint32_t)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
197 fatal_error("Failed to load required buffer of size %d\n", len);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
198 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
199 for(; len != 0; len--, dst++) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
200 uint32_t value = buf->data[buf->cur_pos++] << 24;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
201 value |= buf->data[buf->cur_pos++] << 16;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
202 value |= buf->data[buf->cur_pos++] << 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
203 value |= buf->data[buf->cur_pos++];
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
204 *dst = value;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
205 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
206 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
207
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
208 void load_section(deserialize_buffer *buf)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
209 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
210 if (!buf->handlers) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
211 fatal_error("load_section called on a deserialize_buffer with no handlers registered\n");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
212 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
213 uint16_t section_id = load_int16(buf);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
214 uint32_t size = load_int32(buf);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
215 if (size > (buf->size - buf->cur_pos)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
216 fatal_error("Section is bigger than remaining space in file");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
217 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
218 if (section_id > buf->max_handler || !buf->handlers[section_id].fun) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
219 warning("No handler for section ID %d, save state may be from a newer version\n", section_id);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
220 buf->cur_pos += size;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
221 return;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
222 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
223 deserialize_buffer section;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
224 init_deserialize(&section, buf->data + buf->cur_pos, size);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
225 buf->handlers[section_id].fun(&section, buf->handlers[section_id].data);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
226 buf->cur_pos += size;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
227 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
228
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
229 static const char sz_ident[] = "BLSTSZ\x01\x07";
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
230
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
231 uint8_t save_to_file(serialize_buffer *buf, char *path)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
232 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
233 FILE *f = fopen(path, "wb");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
234 if (!f) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
235 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
236 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
237 if (fwrite(sz_ident, 1, sizeof(sz_ident)-1, f) != sizeof(sz_ident)-1) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
238 fclose(f);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
239 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
240 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
241 if (fwrite(buf->data, 1, buf->size, f) != buf->size) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
242 fclose(f);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
243 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
244 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
245 fclose(f);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
246 return 1;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
247 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
248
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
249 uint8_t load_from_file(deserialize_buffer *buf, char *path)
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
250 {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
251 FILE *f = fopen(path, "rb");
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
252 if (!f) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
253 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
254 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
255 char ident[sizeof(sz_ident)-1];
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
256 long size = file_size(f);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
257 if (size < sizeof(ident)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
258 fclose(f);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
259 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
260 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
261 if (fread(ident, 1, sizeof(ident), f) != sizeof(ident)) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
262 fclose(f);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
263 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
264 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
265 if (memcmp(ident, sz_ident, sizeof(ident))) {
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
266 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
267 }
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
268 buf->size = size - sizeof(ident);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
269 buf->cur_pos = 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
270 buf->data = malloc(buf->size);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
271 buf->handlers = NULL;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
272 buf->max_handler = 8;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
273 if (fread(buf->data, 1, buf->size, f) != buf->size) {
1428
2540c05520f2 New savestates are working. New config file option for selecting format states will be saved in. Mostly complete, needs a little more work before release
Michael Pavone <pavone@retrodev.com>
parents: 1427
diff changeset
274 fclose(f);
1427
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
275 free(buf->data);
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
276 buf->data = NULL;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
277 buf->size = 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
278 return 0;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
279 }
1428
2540c05520f2 New savestates are working. New config file option for selecting format states will be saved in. Mostly complete, needs a little more work before release
Michael Pavone <pavone@retrodev.com>
parents: 1427
diff changeset
280 fclose(f);
1427
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
281 return 1;
4e5797b3935a WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
282 }