Mercurial > repos > blastem
comparison blastem.c @ 1648:b7ecd0d6a77b mame_interp
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 25 Dec 2018 11:12:26 -0800 |
parents | 2455662378ed 360d5bab199f |
children | 956c1cce05e2 |
comparison
equal
deleted
inserted
replaced
1509:36732f5c2281 | 1648:b7ecd0d6a77b |
---|---|
25 #include "util.h" | 25 #include "util.h" |
26 #include "romdb.h" | 26 #include "romdb.h" |
27 #include "terminal.h" | 27 #include "terminal.h" |
28 #include "arena.h" | 28 #include "arena.h" |
29 #include "config.h" | 29 #include "config.h" |
30 #include "bindings.h" | |
30 #include "menu.h" | 31 #include "menu.h" |
31 | 32 #include "zip.h" |
32 #define BLASTEM_VERSION "0.5.2-pre" | 33 #ifndef DISABLE_NUKLEAR |
34 #include "nuklear_ui/blastem_nuklear.h" | |
35 #endif | |
36 | |
37 #define BLASTEM_VERSION "0.6.0-pre" | |
33 | 38 |
34 #ifdef __ANDROID__ | 39 #ifdef __ANDROID__ |
35 #define FULLSCREEN_DEFAULT 1 | 40 #define FULLSCREEN_DEFAULT 1 |
36 #else | 41 #else |
37 #define FULLSCREEN_DEFAULT 0 | 42 #define FULLSCREEN_DEFAULT 0 |
49 #define SMD_MAGIC1 0x03 | 54 #define SMD_MAGIC1 0x03 |
50 #define SMD_MAGIC2 0xAA | 55 #define SMD_MAGIC2 0xAA |
51 #define SMD_MAGIC3 0xBB | 56 #define SMD_MAGIC3 0xBB |
52 #define SMD_BLOCK_SIZE 0x4000 | 57 #define SMD_BLOCK_SIZE 0x4000 |
53 | 58 |
54 int load_smd_rom(long filesize, FILE * f, void **buffer) | 59 #ifdef DISABLE_ZLIB |
60 #define ROMFILE FILE* | |
61 #define romopen fopen | |
62 #define romread fread | |
63 #define romseek fseek | |
64 #define romgetc fgetc | |
65 #define romclose fclose | |
66 #else | |
67 #include "zlib/zlib.h" | |
68 #define ROMFILE gzFile | |
69 #define romopen gzopen | |
70 #define romread gzfread | |
71 #define romseek gzseek | |
72 #define romgetc gzgetc | |
73 #define romclose gzclose | |
74 #endif | |
75 | |
76 int load_smd_rom(ROMFILE f, void **buffer) | |
55 { | 77 { |
56 uint8_t block[SMD_BLOCK_SIZE]; | 78 uint8_t block[SMD_BLOCK_SIZE]; |
57 filesize -= SMD_HEADER_SIZE; | 79 romseek(f, SMD_HEADER_SIZE, SEEK_SET); |
58 fseek(f, SMD_HEADER_SIZE, SEEK_SET); | 80 |
59 | 81 size_t filesize = 512 * 1024; |
60 uint16_t *dst = *buffer = malloc(nearest_pow2(filesize)); | 82 size_t readsize = 0; |
61 int rom_size = filesize; | 83 uint16_t *dst = malloc(filesize); |
62 while (filesize > 0) { | 84 |
63 fread(block, 1, SMD_BLOCK_SIZE, f); | 85 |
64 for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) { | 86 size_t read; |
65 *(dst++) = *low << 8 | *high; | 87 do { |
66 } | 88 if ((readsize + SMD_BLOCK_SIZE > filesize)) { |
67 filesize -= SMD_BLOCK_SIZE; | 89 filesize *= 2; |
68 } | 90 dst = realloc(dst, filesize); |
69 return rom_size; | 91 } |
70 } | 92 read = romread(block, 1, SMD_BLOCK_SIZE, f); |
71 | 93 if (read > 0) { |
72 uint32_t load_rom(char * filename, void **dst, system_type *stype) | 94 for (uint8_t *low = block, *high = (block+read/2), *end = block+read; high < end; high++, low++) { |
95 *(dst++) = *low << 8 | *high; | |
96 } | |
97 readsize += read; | |
98 } | |
99 } while(read > 0); | |
100 romclose(f); | |
101 | |
102 *buffer = dst; | |
103 | |
104 return readsize; | |
105 } | |
106 | |
107 uint32_t load_rom_zip(const char *filename, void **dst) | |
108 { | |
109 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom"}; | |
110 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts); | |
111 zip_file *z = zip_open(filename); | |
112 if (!z) { | |
113 return 0; | |
114 } | |
115 | |
116 for (uint32_t i = 0; i < z->num_entries; i++) | |
117 { | |
118 char *ext = path_extension(z->entries[i].name); | |
119 if (!ext) { | |
120 continue; | |
121 } | |
122 for (uint32_t j = 0; j < num_exts; j++) | |
123 { | |
124 if (!strcasecmp(ext, valid_exts[j])) { | |
125 size_t out_size = nearest_pow2(z->entries[i].size); | |
126 *dst = zip_read(z, i, &out_size); | |
127 if (*dst) { | |
128 free(ext); | |
129 zip_close(z); | |
130 return out_size; | |
131 } | |
132 } | |
133 } | |
134 free(ext); | |
135 } | |
136 zip_close(z); | |
137 return 0; | |
138 } | |
139 | |
140 uint32_t load_rom(const char * filename, void **dst, system_type *stype) | |
73 { | 141 { |
74 uint8_t header[10]; | 142 uint8_t header[10]; |
75 FILE * f = fopen(filename, "rb"); | 143 char *ext = path_extension(filename); |
144 if (!strcasecmp(ext, "zip")) { | |
145 free(ext); | |
146 return load_rom_zip(filename, dst); | |
147 } | |
148 free(ext); | |
149 ROMFILE f = romopen(filename, "rb"); | |
76 if (!f) { | 150 if (!f) { |
77 return 0; | 151 return 0; |
78 } | 152 } |
79 if (sizeof(header) != fread(header, 1, sizeof(header), f)) { | 153 if (sizeof(header) != romread(header, 1, sizeof(header), f)) { |
80 fatal_error("Error reading from %s\n", filename); | 154 fatal_error("Error reading from %s\n", filename); |
81 } | 155 } |
82 fseek(f, 0, SEEK_END); | 156 |
83 long filesize = ftell(f); | |
84 fseek(f, 0, SEEK_SET); | |
85 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) { | 157 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) { |
86 int i; | 158 int i; |
87 for (i = 3; i < 8; i++) { | 159 for (i = 3; i < 8; i++) { |
88 if (header[i] != 0) { | 160 if (header[i] != 0) { |
89 break; | 161 break; |
94 fatal_error("%s is a split SMD ROM which is not currently supported", filename); | 166 fatal_error("%s is a split SMD ROM which is not currently supported", filename); |
95 } | 167 } |
96 if (stype) { | 168 if (stype) { |
97 *stype = SYSTEM_GENESIS; | 169 *stype = SYSTEM_GENESIS; |
98 } | 170 } |
99 return load_smd_rom(filesize, f, dst); | 171 return load_smd_rom(f, dst); |
100 } | 172 } |
101 } | 173 } |
102 *dst = malloc(nearest_pow2(filesize)); | 174 |
103 if (filesize != fread(*dst, 1, filesize, f)) { | 175 size_t filesize = 512 * 1024; |
104 fatal_error("Error reading from %s\n", filename); | 176 size_t readsize = sizeof(header); |
105 } | 177 |
106 fclose(f); | 178 char *buf = malloc(filesize); |
107 return filesize; | 179 memcpy(buf, header, readsize); |
180 | |
181 size_t read; | |
182 do { | |
183 read = romread(buf + readsize, 1, filesize - readsize, f); | |
184 if (read > 0) { | |
185 readsize += read; | |
186 if (readsize == filesize) { | |
187 int one_more = romgetc(f); | |
188 if (one_more >= 0) { | |
189 filesize *= 2; | |
190 buf = realloc(buf, filesize); | |
191 buf[readsize++] = one_more; | |
192 } else { | |
193 read = 0; | |
194 } | |
195 } | |
196 } | |
197 } while (read > 0); | |
198 | |
199 *dst = buf; | |
200 | |
201 romclose(f); | |
202 return readsize; | |
108 } | 203 } |
109 | 204 |
110 | 205 |
111 | 206 |
112 int break_on_sync = 0; | 207 int break_on_sync = 0; |
155 warning("Failed to create save directory %s\n", save_dir); | 250 warning("Failed to create save directory %s\n", save_dir); |
156 } | 251 } |
157 return save_dir; | 252 return save_dir; |
158 } | 253 } |
159 | 254 |
160 void setup_saves(system_media *media, rom_info *info, system_header *context) | 255 void setup_saves(system_media *media, system_header *context) |
161 { | 256 { |
162 static uint8_t persist_save_registered; | 257 static uint8_t persist_save_registered; |
258 rom_info *info = &context->info; | |
163 char *save_dir = get_save_dir(info->is_save_lock_on ? media->chain : media); | 259 char *save_dir = get_save_dir(info->is_save_lock_on ? media->chain : media); |
164 char const *parts[] = {save_dir, PATH_SEP, info->save_type == SAVE_I2C ? "save.eeprom" : info->save_type == SAVE_NOR ? "save.nor" : "save.sram"}; | 260 char const *parts[] = {save_dir, PATH_SEP, info->save_type == SAVE_I2C ? "save.eeprom" : info->save_type == SAVE_NOR ? "save.nor" : "save.sram"}; |
165 free(save_filename); | 261 free(save_filename); |
166 save_filename = alloc_concat_m(3, parts); | 262 save_filename = alloc_concat_m(3, parts); |
167 if (info->is_save_lock_on) { | 263 if (info->is_save_lock_on) { |
168 //initial save dir was calculated based on lock-on cartridge because that's where the save device is | 264 //initial save dir was calculated based on lock-on cartridge because that's where the save device is |
169 //save directory used for save states should still be located in the normal place | 265 //save directory used for save states should still be located in the normal place |
170 free(save_dir); | 266 free(save_dir); |
171 save_dir = get_save_dir(media); | 267 parts[0] = save_dir = get_save_dir(media); |
172 } | 268 } |
173 if (use_native_states || context->type != SYSTEM_GENESIS) { | 269 if (use_native_states || context->type != SYSTEM_GENESIS) { |
174 parts[2] = "quicksave.state"; | 270 parts[2] = "quicksave.state"; |
175 } else { | 271 } else { |
176 parts[2] = "quicksave.gst"; | 272 parts[2] = "quicksave.gst"; |
185 persist_save_registered = 1; | 281 persist_save_registered = 1; |
186 } | 282 } |
187 } | 283 } |
188 } | 284 } |
189 | 285 |
286 void apply_updated_config(void) | |
287 { | |
288 render_config_updated(); | |
289 if (current_system && current_system->config_updated) { | |
290 current_system->config_updated(current_system); | |
291 } | |
292 } | |
293 | |
190 static void on_drag_drop(const char *filename) | 294 static void on_drag_drop(const char *filename) |
191 { | 295 { |
192 if (current_system->next_rom) { | 296 if (current_system) { |
193 free(current_system->next_rom); | 297 if (current_system->next_rom) { |
194 } | 298 free(current_system->next_rom); |
195 current_system->next_rom = strdup(filename); | 299 } |
196 current_system->request_exit(current_system); | 300 current_system->next_rom = strdup(filename); |
197 if (menu_system && menu_system->type == SYSTEM_GENESIS) { | 301 current_system->request_exit(current_system); |
198 genesis_context *gen = (genesis_context *)menu_system; | 302 if (menu_system && menu_system->type == SYSTEM_GENESIS) { |
199 if (gen->extra) { | 303 genesis_context *gen = (genesis_context *)menu_system; |
200 menu_context *menu = gen->extra; | 304 if (gen->extra) { |
201 menu->external_game_load = 1; | 305 menu_context *menu = gen->extra; |
202 } else { | 306 menu->external_game_load = 1; |
203 puts("No extra"); | 307 } |
204 } | 308 } |
205 } else { | 309 } else { |
206 puts("no menu"); | 310 init_system_with_media(filename, SYSTEM_UNKNOWN); |
207 } | 311 } |
312 #ifndef DISABLE_NUKLEAR | |
313 if (is_nuklear_active()) { | |
314 show_play_view(); | |
315 } | |
316 #endif | |
208 } | 317 } |
209 | 318 |
210 static system_media cart, lock_on; | 319 static system_media cart, lock_on; |
211 void reload_media(void) | 320 void reload_media(void) |
212 { | 321 { |
322 if (!current_system) { | |
323 return; | |
324 } | |
213 if (current_system->next_rom) { | 325 if (current_system->next_rom) { |
214 free(current_system->next_rom); | 326 free(current_system->next_rom); |
215 } | 327 } |
216 char const *parts[] = { | 328 char const *parts[] = { |
217 cart.dir, PATH_SEP, cart.name, ".", cart.extension | 329 cart.dir, PATH_SEP, cart.name, ".", cart.extension |
236 lock_on.name = basename_no_extension(lock_on_path); | 348 lock_on.name = basename_no_extension(lock_on_path); |
237 lock_on.extension = path_extension(lock_on_path); | 349 lock_on.extension = path_extension(lock_on_path); |
238 lock_on.size = load_rom(lock_on_path, &lock_on.buffer, NULL); | 350 lock_on.size = load_rom(lock_on_path, &lock_on.buffer, NULL); |
239 } | 351 } |
240 | 352 |
353 static uint32_t opts = 0; | |
354 static uint8_t force_region = 0; | |
355 void init_system_with_media(const char *path, system_type force_stype) | |
356 { | |
357 if (game_system) { | |
358 game_system->persist_save(game_system); | |
359 #ifdef USE_NATIVE | |
360 //swap to game context arena and mark all allocated pages in it free | |
361 if (current_system == menu_system) { | |
362 current_system->arena = set_current_arena(game_system->arena); | |
363 } | |
364 mark_all_free(); | |
365 #endif | |
366 game_system->free_context(game_system); | |
367 #ifdef USE_NATIVE | |
368 } else if(current_system) { | |
369 //start a new arena and save old one in suspended system context | |
370 current_system->arena = start_new_arena(); | |
371 #endif | |
372 } | |
373 system_type stype = SYSTEM_UNKNOWN; | |
374 if (!(cart.size = load_rom(path, &cart.buffer, &stype))) { | |
375 fatal_error("Failed to open %s for reading\n", path); | |
376 } | |
377 free(cart.dir); | |
378 free(cart.name); | |
379 free(cart.extension); | |
380 cart.dir = path_dirname(path); | |
381 cart.name = basename_no_extension(path); | |
382 cart.extension = path_extension(path); | |
383 if (force_stype != SYSTEM_UNKNOWN) { | |
384 stype = force_stype; | |
385 } | |
386 if (stype == SYSTEM_UNKNOWN) { | |
387 stype = detect_system_type(&cart); | |
388 } | |
389 if (stype == SYSTEM_UNKNOWN) { | |
390 fatal_error("Failed to detect system type for %s\n", path); | |
391 } | |
392 //allocate new system context | |
393 game_system = alloc_config_system(stype, &cart, opts, force_region); | |
394 if (!game_system) { | |
395 fatal_error("Failed to configure emulated machine for %s\n", path); | |
396 } | |
397 if (menu_system) { | |
398 menu_system->next_context = game_system; | |
399 } | |
400 game_system->next_context = menu_system; | |
401 setup_saves(&cart, game_system); | |
402 update_title(game_system->info.name); | |
403 } | |
404 | |
241 int main(int argc, char ** argv) | 405 int main(int argc, char ** argv) |
242 { | 406 { |
243 set_exe_str(argv[0]); | 407 set_exe_str(argv[0]); |
244 config = load_config(); | 408 config = load_config(); |
245 int width = -1; | 409 int width = -1; |
246 int height = -1; | 410 int height = -1; |
247 int debug = 0; | 411 int debug = 0; |
248 uint32_t opts = 0; | |
249 int loaded = 0; | 412 int loaded = 0; |
250 system_type stype = SYSTEM_UNKNOWN, force_stype = SYSTEM_UNKNOWN; | 413 system_type stype = SYSTEM_UNKNOWN, force_stype = SYSTEM_UNKNOWN; |
251 uint8_t force_region = 0; | |
252 char * romfname = NULL; | 414 char * romfname = NULL; |
253 char * statefile = NULL; | 415 char * statefile = NULL; |
254 debugger_type dtype = DEBUGGER_NATIVE; | 416 debugger_type dtype = DEBUGGER_NATIVE; |
255 uint8_t start_in_debugger = 0; | 417 uint8_t start_in_debugger = 0; |
256 uint8_t fullscreen = FULLSCREEN_DEFAULT, use_gl = 1; | 418 uint8_t fullscreen = FULLSCREEN_DEFAULT, use_gl = 1; |
385 width = atoi(argv[i]); | 547 width = atoi(argv[i]); |
386 } else if (height < 0) { | 548 } else if (height < 0) { |
387 height = atoi(argv[i]); | 549 height = atoi(argv[i]); |
388 } | 550 } |
389 } | 551 } |
552 | |
553 int def_width = 0, def_height = 0; | |
554 char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval; | |
555 if (config_width) { | |
556 def_width = atoi(config_width); | |
557 } | |
558 if (!def_width) { | |
559 def_width = 640; | |
560 } | |
561 char *config_height = tern_find_path(config, "video\0height\0", TVAL_PTR).ptrval; | |
562 if (config_height) { | |
563 def_height = atoi(config_height); | |
564 } | |
565 if (!def_height) { | |
566 def_height = -1; | |
567 } | |
568 width = width < 1 ? def_width : width; | |
569 height = height < 1 ? def_height : height; | |
570 | |
571 char *config_fullscreen = tern_find_path(config, "video\0fullscreen\0", TVAL_PTR).ptrval; | |
572 if (config_fullscreen && !strcmp("on", config_fullscreen)) { | |
573 fullscreen = !fullscreen; | |
574 } | |
575 if (!headless) { | |
576 render_init(width, height, "BlastEm", fullscreen); | |
577 render_set_drag_drop_handler(on_drag_drop); | |
578 } | |
579 set_bindings(); | |
580 | |
390 uint8_t menu = !loaded; | 581 uint8_t menu = !loaded; |
391 if (!loaded) { | 582 uint8_t use_nuklear = 0; |
583 #ifndef DISABLE_NUKLEAR | |
584 use_nuklear = is_nuklear_available(); | |
585 #endif | |
586 if (!loaded && !use_nuklear) { | |
392 //load menu | 587 //load menu |
393 romfname = tern_find_path(config, "ui\0rom\0", TVAL_PTR).ptrval; | 588 romfname = tern_find_path(config, "ui\0rom\0", TVAL_PTR).ptrval; |
394 if (!romfname) { | 589 if (!romfname) { |
395 romfname = "menu.bin"; | 590 romfname = "menu.bin"; |
396 } | 591 } |
414 cart.dir = path_dirname(romfname); | 609 cart.dir = path_dirname(romfname); |
415 cart.name = basename_no_extension(romfname); | 610 cart.name = basename_no_extension(romfname); |
416 cart.extension = path_extension(romfname); | 611 cart.extension = path_extension(romfname); |
417 loaded = 1; | 612 loaded = 1; |
418 } | 613 } |
419 | |
420 int def_width = 0, def_height = 0; | |
421 char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval; | |
422 if (config_width) { | |
423 def_width = atoi(config_width); | |
424 } | |
425 if (!def_width) { | |
426 def_width = 640; | |
427 } | |
428 char *config_height = tern_find_path(config, "video\0height\0", TVAL_PTR).ptrval; | |
429 if (config_height) { | |
430 def_height = atoi(config_height); | |
431 } | |
432 if (!def_height) { | |
433 def_height = -1; | |
434 } | |
435 width = width < 1 ? def_width : width; | |
436 height = height < 1 ? def_height : height; | |
437 | |
438 char *config_fullscreen = tern_find_path(config, "video\0fullscreen\0", TVAL_PTR).ptrval; | |
439 if (config_fullscreen && !strcmp("on", config_fullscreen)) { | |
440 fullscreen = !fullscreen; | |
441 } | |
442 if (!headless) { | |
443 render_init(width, height, "BlastEm", fullscreen); | |
444 render_set_drag_drop_handler(on_drag_drop); | |
445 } | |
446 | |
447 if (stype == SYSTEM_UNKNOWN) { | |
448 stype = detect_system_type(&cart); | |
449 } | |
450 if (stype == SYSTEM_UNKNOWN) { | |
451 fatal_error("Failed to detect system type for %s\n", romfname); | |
452 } | |
453 rom_info info; | |
454 current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region, &info); | |
455 if (!current_system) { | |
456 fatal_error("Failed to configure emulated machine for %s\n", romfname); | |
457 } | |
458 char *state_format = tern_find_path(config, "ui\0state_format\0", TVAL_PTR).ptrval; | 614 char *state_format = tern_find_path(config, "ui\0state_format\0", TVAL_PTR).ptrval; |
459 if (state_format && !strcmp(state_format, "gst")) { | 615 if (state_format && !strcmp(state_format, "gst")) { |
460 use_native_states = 0; | 616 use_native_states = 0; |
461 } else if (state_format && strcmp(state_format, "native")) { | 617 } else if (state_format && strcmp(state_format, "native")) { |
462 warning("%s is not a valid value for the ui.state_format setting. Valid values are gst and native\n", state_format); | 618 warning("%s is not a valid value for the ui.state_format setting. Valid values are gst and native\n", state_format); |
463 } | 619 } |
464 setup_saves(&cart, &info, current_system); | 620 |
465 update_title(info.name); | 621 if (loaded) { |
466 if (menu) { | 622 if (stype == SYSTEM_UNKNOWN) { |
467 menu_system = current_system; | 623 stype = detect_system_type(&cart); |
468 } else { | 624 } |
469 game_system = current_system; | 625 if (stype == SYSTEM_UNKNOWN) { |
470 } | 626 fatal_error("Failed to detect system type for %s\n", romfname); |
471 | 627 } |
628 current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region); | |
629 if (!current_system) { | |
630 fatal_error("Failed to configure emulated machine for %s\n", romfname); | |
631 } | |
632 | |
633 setup_saves(&cart, current_system); | |
634 update_title(current_system->info.name); | |
635 if (menu) { | |
636 menu_system = current_system; | |
637 } else { | |
638 game_system = current_system; | |
639 } | |
640 } | |
641 | |
642 #ifndef DISABLE_NUKLEAR | |
643 if (use_nuklear) { | |
644 blastem_nuklear_init(!menu); | |
645 current_system = game_system; | |
646 menu = 0; | |
647 } | |
648 #endif | |
649 | |
472 current_system->debugger_type = dtype; | 650 current_system->debugger_type = dtype; |
473 current_system->enter_debugger = start_in_debugger && menu == debug_target; | 651 current_system->enter_debugger = start_in_debugger && menu == debug_target; |
474 current_system->start_context(current_system, menu ? NULL : statefile); | 652 current_system->start_context(current_system, menu ? NULL : statefile); |
475 for(;;) | 653 for(;;) |
476 { | 654 { |
478 break; | 656 break; |
479 } | 657 } |
480 if (current_system->next_rom) { | 658 if (current_system->next_rom) { |
481 char *next_rom = current_system->next_rom; | 659 char *next_rom = current_system->next_rom; |
482 current_system->next_rom = NULL; | 660 current_system->next_rom = NULL; |
483 if (game_system) { | 661 init_system_with_media(next_rom, force_stype); |
484 game_system->persist_save(game_system); | |
485 #ifdef USE_NATIVE | |
486 //swap to game context arena and mark all allocated pages in it free | |
487 if (menu) { | |
488 current_system->arena = set_current_arena(game_system->arena); | |
489 } | |
490 mark_all_free(); | |
491 #endif | |
492 game_system->free_context(game_system); | |
493 } else { | |
494 #ifdef USE_NATIVE | |
495 //start a new arena and save old one in suspended genesis context | |
496 current_system->arena = start_new_arena(); | |
497 #endif | |
498 } | |
499 if (!(cart.size = load_rom(next_rom, &cart.buffer, &stype))) { | |
500 fatal_error("Failed to open %s for reading\n", next_rom); | |
501 } | |
502 free(cart.dir); | |
503 free(cart.name); | |
504 free(cart.extension); | |
505 cart.dir = path_dirname(next_rom); | |
506 cart.name = basename_no_extension(next_rom); | |
507 cart.extension = path_extension(next_rom); | |
508 stype = force_stype; | |
509 if (stype == SYSTEM_UNKNOWN) { | |
510 stype = detect_system_type(&cart); | |
511 } | |
512 if (stype == SYSTEM_UNKNOWN) { | |
513 fatal_error("Failed to detect system type for %s\n", next_rom); | |
514 } | |
515 //allocate new system context | |
516 game_system = alloc_config_system(stype, &cart, opts,force_region, &info); | |
517 if (!game_system) { | |
518 fatal_error("Failed to configure emulated machine for %s\n", next_rom); | |
519 } | |
520 if (menu_system) { | |
521 menu_system->next_context = game_system; | |
522 } | |
523 game_system->next_context = menu_system; | |
524 setup_saves(&cart, &info, game_system); | |
525 update_title(info.name); | |
526 free(next_rom); | 662 free(next_rom); |
527 menu = 0; | 663 menu = 0; |
528 current_system = game_system; | 664 current_system = game_system; |
529 current_system->debugger_type = dtype; | 665 current_system->debugger_type = dtype; |
530 current_system->enter_debugger = start_in_debugger && menu == debug_target; | 666 current_system->enter_debugger = start_in_debugger && menu == debug_target; |
534 current_system->arena = set_current_arena(game_system->arena); | 670 current_system->arena = set_current_arena(game_system->arena); |
535 #endif | 671 #endif |
536 current_system = game_system; | 672 current_system = game_system; |
537 menu = 0; | 673 menu = 0; |
538 current_system->resume_context(current_system); | 674 current_system->resume_context(current_system); |
539 } else if (!menu && menu_system) { | 675 } else if (!menu && (menu_system || use_nuklear)) { |
676 if (use_nuklear) { | |
677 #ifndef DISABLE_NUKLEAR | |
678 ui_idle_loop(); | |
679 #endif | |
680 } else { | |
540 #ifdef USE_NATIVE | 681 #ifdef USE_NATIVE |
541 current_system->arena = set_current_arena(menu_system->arena); | 682 current_system->arena = set_current_arena(menu_system->arena); |
542 #endif | 683 #endif |
543 current_system = menu_system; | 684 current_system = menu_system; |
544 menu = 1; | 685 menu = 1; |
545 current_system->resume_context(current_system); | 686 } |
687 if (!current_system->next_rom) { | |
688 current_system->resume_context(current_system); | |
689 } | |
546 } else { | 690 } else { |
547 break; | 691 break; |
548 } | 692 } |
549 } | 693 } |
550 | 694 |