Mercurial > repos > blastem
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 |
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 | 23 if (amount < buf->storage) { |
24 buf->storage *= 2; | |
25 } else { | |
26 //doublign isn't enough, increase by the precise amount needed | |
27 buf->storage += amount - (buf->storage - buf->size); | |
28 } | |
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(§ion, 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(§ion, 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 } |