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;