comparison system.c @ 2546:6aa3025bbf5f

Merge
author Michael Pavone <pavone@retrodev.com>
date Thu, 02 Jan 2025 23:03:50 -0800
parents c076a96f1668
children c30f0a288ccf
comparison
equal deleted inserted replaced
2544:99e59fdddbc3 2546:6aa3025bbf5f
6 #include "sms.h" 6 #include "sms.h"
7 #include "mediaplayer.h" 7 #include "mediaplayer.h"
8 #include "coleco.h" 8 #include "coleco.h"
9 #include "paths.h" 9 #include "paths.h"
10 #include "util.h" 10 #include "util.h"
11 #include "cdimage.h"
12
13 #define SMD_HEADER_SIZE 512
14 #define SMD_MAGIC1 0x03
15 #define SMD_MAGIC2 0xAA
16 #define SMD_MAGIC3 0xBB
17 #define SMD_BLOCK_SIZE 0x4000
18
19 #ifdef DISABLE_ZLIB
20 #define ROMFILE FILE*
21 #define romopen fopen
22 #define romread fread
23 #define romseek fseek
24 #define romgetc fgetc
25 #define romclose fclose
26 #else
27 #include "zlib/zlib.h"
28 #define ROMFILE gzFile
29 #define romopen gzopen
30 #define romread gzfread
31 #define romseek gzseek
32 #define romgetc gzgetc
33 #define romclose gzclose
34 #endif
35
36 uint16_t *process_smd_block(uint16_t *dst, uint8_t *src, size_t bytes)
37 {
38 for (uint8_t *low = src, *high = (src+bytes/2), *end = src+bytes; high < end; high++, low++) {
39 *(dst++) = *low << 8 | *high;
40 }
41 return dst;
42 }
43
44 int load_smd_rom(ROMFILE f, void **buffer)
45 {
46 uint8_t block[SMD_BLOCK_SIZE];
47 romseek(f, SMD_HEADER_SIZE, SEEK_SET);
48
49 size_t filesize = 512 * 1024;
50 size_t readsize = 0;
51 uint16_t *dst, *buf;
52 dst = buf = malloc(filesize);
53
54
55 size_t read;
56 do {
57 if ((readsize + SMD_BLOCK_SIZE > filesize)) {
58 filesize *= 2;
59 buf = realloc(buf, filesize);
60 dst = buf + readsize/sizeof(uint16_t);
61 }
62 read = romread(block, 1, SMD_BLOCK_SIZE, f);
63 if (read > 0) {
64 dst = process_smd_block(dst, block, read);
65 readsize += read;
66 }
67 } while(read > 0);
68 romclose(f);
69
70 *buffer = buf;
71
72 return readsize;
73 }
74
75 uint8_t is_smd_format(const char *filename, uint8_t *header)
76 {
77 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) {
78 int i;
79 for (i = 3; i < 8; i++) {
80 if (header[i] != 0) {
81 return 0;
82 }
83 }
84 if (i == 8) {
85 if (header[2]) {
86 fatal_error("%s is a split SMD ROM which is not currently supported", filename);
87 }
88 return 1;
89 }
90 }
91 return 0;
92 }
93
94 #ifndef IS_LIB
95 uint32_t load_media_zip(const char *filename, system_media *dst)
96 {
97 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "gg", "rom", "smd", "sg", "sc", "sf7"};
98 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts);
99 zip_file *z = zip_open(filename);
100 if (!z) {
101 return 0;
102 }
103
104 for (uint32_t i = 0; i < z->num_entries; i++)
105 {
106 char *ext = path_extension(z->entries[i].name);
107 if (!ext) {
108 continue;
109 }
110 for (uint32_t j = 0; j < num_exts; j++)
111 {
112 if (!strcasecmp(ext, valid_exts[j])) {
113 size_t out_size = nearest_pow2(z->entries[i].size);
114 dst->buffer = zip_read(z, i, &out_size);
115 if (dst->buffer) {
116 if (is_smd_format(z->entries[i].name, dst->buffer)) {
117 size_t offset;
118 for (offset = 0; offset + SMD_BLOCK_SIZE + SMD_HEADER_SIZE <= out_size; offset += SMD_BLOCK_SIZE)
119 {
120 uint8_t tmp[SMD_BLOCK_SIZE];
121 uint8_t *u8dst = dst->buffer;
122 memcpy(tmp, u8dst + offset + SMD_HEADER_SIZE, SMD_BLOCK_SIZE);
123 process_smd_block((void *)(u8dst + offset), tmp, SMD_BLOCK_SIZE);
124 }
125 out_size = offset;
126 }
127 dst->extension = ext;
128 dst->dir = path_dirname(filename);
129 if (!dst->dir) {
130 dst->dir = path_current_dir();
131 }
132 dst->name = basename_no_extension(filename);
133 dst->size = out_size;
134 dst->zip = z;
135 return out_size;
136 }
137 }
138 }
139 free(ext);
140 }
141 zip_close(z);
142 return 0;
143 }
144 #endif
145
146 uint32_t load_media(char * filename, system_media *dst, system_type *stype)
147 {
148 uint8_t header[10];
149 #ifndef IS_LIB
150 if (dst->zip) {
151 zip_close(dst->zip);
152 }
153 #endif
154 dst->orig_path = filename;
155 char *ext = path_extension(filename);
156 #ifndef IS_LIB
157 if (ext && !strcasecmp(ext, "zip")) {
158 free(ext);
159 return load_media_zip(filename, dst);
160 }
161 #endif
162 if (ext && !strcasecmp(ext, "iso")) {
163 if (stype) {
164 *stype = SYSTEM_SEGACD;
165 }
166 return make_iso_media(dst, filename);
167 }
168
169 ROMFILE f = romopen(filename, "rb");
170 if (!f) {
171 free(ext);
172 return 0;
173 }
174 #ifndef DISABLE_ZLIB
175 char *to_free = NULL;
176 if (!gzdirect(f) && ext && !strcasecmp(ext, "gz")) {
177 size_t without_gz = strlen(filename) - 2;
178 to_free = calloc(1, without_gz);
179 memcpy(to_free, filename, without_gz - 1);
180 to_free[without_gz - 1] = 0;
181 free(ext);
182 filename = to_free;
183 ext = path_extension(filename);
184 }
185 #endif //DISABLE_ZLIB
186
187 if (sizeof(header) != romread(header, 1, sizeof(header), f)) {
188 fatal_error("Error reading from %s\n", filename);
189 }
190
191 uint32_t ret = 0;
192 if (is_smd_format(filename, header)) {
193 if (stype) {
194 *stype = SYSTEM_GENESIS;
195 }
196 ret = load_smd_rom(f, &dst->buffer);
197 }
198
199 if (!ret) {
200 size_t filesize = 512 * 1024;
201 size_t readsize = sizeof(header);
202
203 char *buf = malloc(filesize);
204 memcpy(buf, header, readsize);
205
206 size_t read;
207 do {
208 read = romread(buf + readsize, 1, filesize - readsize, f);
209 if (read > 0) {
210 readsize += read;
211 if (readsize == filesize) {
212 int one_more = romgetc(f);
213 if (one_more >= 0) {
214 filesize *= 2;
215 buf = realloc(buf, filesize);
216 buf[readsize++] = one_more;
217 } else {
218 read = 0;
219 }
220 }
221 }
222 } while (read > 0);
223 dst->buffer = buf;
224 ret = (uint32_t)readsize;
225 }
226 dst->dir = path_dirname(filename);
227 if (!dst->dir) {
228 dst->dir = path_current_dir();
229 }
230 dst->name = basename_no_extension(filename);
231 dst->extension = ext;
232 dst->size = ret;
233 romclose(f);
234 if (!strcasecmp(dst->extension, "cue")) {
235 if (parse_cue(dst)) {
236 if (stype) {
237 *stype = SYSTEM_SEGACD;
238 }
239 }
240 } else if (!strcasecmp(dst->extension, "toc")) {
241 if (parse_toc(dst)) {
242 if (stype) {
243 *stype = SYSTEM_SEGACD;
244 }
245 }
246 }
247 #ifndef DISABLE_ZLIB
248 if (to_free) {
249 free(to_free);
250 }
251 #endif
252
253 return ret;
254 }
11 255
12 uint8_t safe_cmp(char *str, long offset, uint8_t *buffer, long filesize) 256 uint8_t safe_cmp(char *str, long offset, uint8_t *buffer, long filesize)
13 { 257 {
14 long len = strlen(str); 258 long len = strlen(str);
15 return filesize >= offset+len && !memcmp(str, buffer + offset, len); 259 return filesize >= offset+len && !memcmp(str, buffer + offset, len);