Mercurial > repos > blastem
annotate serialize.c @ 1637:95880d947257
Fix for VRAM byte write order broke VDP FIFO testing ROM results. This change cleans up VRAM writes and fixes the regression while preserving the correct VRAM byte write order
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 11 Nov 2018 22:39:29 -0800 |
parents | 2540c05520f2 |
children | c3c62dbf1ceb |
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)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 buf->storage *= 2; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 buf = realloc(buf, buf->storage + sizeof(*buf)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 void save_int32(serialize_buffer *buf, uint32_t val) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 reserve(buf, sizeof(val)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 buf->data[buf->size++] = val >> 24; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 buf->data[buf->size++] = val >> 16; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 buf->data[buf->size++] = val >> 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 buf->data[buf->size++] = val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 void save_int16(serialize_buffer *buf, uint16_t val) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 reserve(buf, sizeof(val)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 buf->data[buf->size++] = val >> 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 buf->data[buf->size++] = val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 } |
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 void save_int8(serialize_buffer *buf, uint8_t val) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 reserve(buf, sizeof(val)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 buf->data[buf->size++] = val; |
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 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 void save_string(serialize_buffer *buf, char *val) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 size_t len = strlen(val); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 save_buffer8(buf, val, len); |
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 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 void save_buffer8(serialize_buffer *buf, void *val, size_t len) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 reserve(buf, len); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 memcpy(&buf->data[buf->size], val, len); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 buf->size += len; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 } |
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 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
|
64 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 reserve(buf, len * sizeof(*val)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 for(; len != 0; len--, val++) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 buf->data[buf->size++] = *val >> 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 buf->data[buf->size++] = *val; |
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 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 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
|
73 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 reserve(buf, len * sizeof(*val)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 for(; len != 0; len--, val++) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 buf->data[buf->size++] = *val >> 24; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 buf->data[buf->size++] = *val >> 16; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 buf->data[buf->size++] = *val >> 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 buf->data[buf->size++] = *val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 void start_section(serialize_buffer *buf, uint16_t section_id) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 save_int16(buf, section_id); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 //reserve some space for size once we end this section |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 reserve(buf, sizeof(uint32_t)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 buf->size += sizeof(uint32_t); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 //save start point for use in end_device |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 buf->current_section_start = buf->size; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 void end_section(serialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 size_t section_size = buf->size - buf->current_section_start; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 if (section_size > 0xFFFFFFFFU) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 fatal_error("Sections larger than 4GB are not supported"); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 uint32_t size = section_size; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 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
|
101 *(field++) = size >> 24; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 *(field++) = size >> 16; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 *(field++) = size >> 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 *(field++) = size; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 buf->current_section_start = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 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
|
109 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 if (section_id > buf->max_handler) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 uint16_t old_max = buf->max_handler; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 if (buf->max_handler < 0x8000) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 buf->max_handler *= 2; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 } else { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 buf->max_handler = 0xFFFF; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 buf->handlers = realloc(buf->handlers, (buf->max_handler+1) * sizeof(handler)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 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
|
119 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 if (!buf->handlers) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 buf->handlers = calloc(buf->max_handler + 1, sizeof(handler)); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 buf->handlers[section_id] = 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 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 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
|
127 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 buf->size = size; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 buf->cur_pos = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 buf->data = data; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 buf->handlers = NULL; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 buf->max_handler = 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
133 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 uint32_t load_int32(deserialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 uint32_t val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 if ((buf->size - buf->cur_pos) < sizeof(val)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 fatal_error("Failed to load required int32 field"); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 val = buf->data[buf->cur_pos++] << 24; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 val |= buf->data[buf->cur_pos++] << 16; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 val |= buf->data[buf->cur_pos++] << 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 val |= buf->data[buf->cur_pos++]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 return val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 uint16_t load_int16(deserialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 uint16_t val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 if ((buf->size - buf->cur_pos) < sizeof(val)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 fatal_error("Failed to load required int16 field"); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 val = buf->data[buf->cur_pos++] << 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
155 val |= buf->data[buf->cur_pos++]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 return val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 } |
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 uint8_t load_int8(deserialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 uint8_t val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 if ((buf->size - buf->cur_pos) < sizeof(val)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 fatal_error("Failed to load required int8 field"); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 val = buf->data[buf->cur_pos++]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 return val; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 void load_buffer8(deserialize_buffer *buf, void *dst, size_t len) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 if ((buf->size - buf->cur_pos) < len) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 fatal_error("Failed to load required buffer of size %d", len); |
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 memcpy(dst, buf->data + buf->cur_pos, len); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
175 buf->cur_pos += len; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 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
|
179 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 if ((buf->size - buf->cur_pos) < len * sizeof(uint16_t)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 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
|
182 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
183 for(; len != 0; len--, dst++) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 uint16_t value = buf->data[buf->cur_pos++] << 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 value |= buf->data[buf->cur_pos++]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 *dst = value; |
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 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 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
|
190 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 if ((buf->size - buf->cur_pos) < len * sizeof(uint32_t)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 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
|
193 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
194 for(; len != 0; len--, dst++) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
195 uint32_t value = buf->data[buf->cur_pos++] << 24; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
196 value |= buf->data[buf->cur_pos++] << 16; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
197 value |= buf->data[buf->cur_pos++] << 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
198 value |= buf->data[buf->cur_pos++]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
199 *dst = value; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
200 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
201 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
202 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 void load_section(deserialize_buffer *buf) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
204 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 if (!buf->handlers) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
206 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
|
207 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
208 uint16_t section_id = load_int16(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
209 uint32_t size = load_int32(buf); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
210 if (size > (buf->size - buf->cur_pos)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
211 fatal_error("Section is bigger than remaining space in file"); |
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 if (section_id > buf->max_handler || !buf->handlers[section_id].fun) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
214 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
|
215 buf->cur_pos += size; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
216 return; |
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 deserialize_buffer section; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
219 init_deserialize(§ion, buf->data + buf->cur_pos, size); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
220 buf->handlers[section_id].fun(§ion, buf->handlers[section_id].data); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
221 buf->cur_pos += size; |
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 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 static const char sz_ident[] = "BLSTSZ\x01\x07"; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 uint8_t save_to_file(serialize_buffer *buf, char *path) |
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 FILE *f = fopen(path, "wb"); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 if (!f) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
230 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
231 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
232 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
|
233 fclose(f); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
234 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
235 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
236 if (fwrite(buf->data, 1, buf->size, f) != buf->size) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
237 fclose(f); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
238 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
239 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
240 fclose(f); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
241 return 1; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
242 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
243 |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
244 uint8_t load_from_file(deserialize_buffer *buf, char *path) |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
245 { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
246 FILE *f = fopen(path, "rb"); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
247 if (!f) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
248 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
249 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
250 char ident[sizeof(sz_ident)-1]; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
251 long size = file_size(f); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
252 if (size < sizeof(ident)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
253 fclose(f); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
254 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
255 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
256 if (fread(ident, 1, sizeof(ident), f) != sizeof(ident)) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
257 fclose(f); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
258 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
259 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
260 if (memcmp(ident, sz_ident, sizeof(ident))) { |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
261 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
262 } |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
263 buf->size = size - sizeof(ident); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
264 buf->cur_pos = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
265 buf->data = malloc(buf->size); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
266 buf->handlers = NULL; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
267 buf->max_handler = 8; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
268 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
|
269 fclose(f); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
270 free(buf->data); |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
271 buf->data = NULL; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
272 buf->size = 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
273 return 0; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
274 } |
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
|
275 fclose(f); |
1427
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
276 return 1; |
4e5797b3935a
WIP - New savestate format
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
277 } |