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