comparison blastem.c @ 1692:5dacaef602a7 segacd

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