comparison blastem.c @ 2053:3414a4423de1 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 15 Jan 2022 13:15:21 -0800
parents 5dacaef602a7 0f54a898db03
children 6399a776e981
comparison
equal deleted inserted replaced
1692:5dacaef602a7 2053:3414a4423de1
9 #include <ctype.h> 9 #include <ctype.h>
10 10
11 #include "system.h" 11 #include "system.h"
12 #include "68kinst.h" 12 #include "68kinst.h"
13 #include "m68k_core.h" 13 #include "m68k_core.h"
14 #ifdef NEW_CORE
15 #include "z80.h"
16 #else
14 #include "z80_to_x86.h" 17 #include "z80_to_x86.h"
18 #endif
15 #include "mem.h" 19 #include "mem.h"
16 #include "vdp.h" 20 #include "vdp.h"
17 #include "render.h" 21 #include "render.h"
18 #include "genesis.h" 22 #include "genesis.h"
19 #include "gdb_remote.h" 23 #include "gdb_remote.h"
24 #include "arena.h" 28 #include "arena.h"
25 #include "config.h" 29 #include "config.h"
26 #include "bindings.h" 30 #include "bindings.h"
27 #include "menu.h" 31 #include "menu.h"
28 #include "zip.h" 32 #include "zip.h"
33 #include "event_log.h"
29 #ifndef DISABLE_NUKLEAR 34 #ifndef DISABLE_NUKLEAR
30 #include "nuklear_ui/blastem_nuklear.h" 35 #include "nuklear_ui/blastem_nuklear.h"
31 #endif 36 #endif
32 37
33 #define BLASTEM_VERSION "0.6.1" 38 #define BLASTEM_VERSION "0.6.3-pre"
34 39
35 #ifdef __ANDROID__ 40 #ifdef __ANDROID__
36 #define FULLSCREEN_DEFAULT 1 41 #define FULLSCREEN_DEFAULT 1
37 #else 42 #else
38 #define FULLSCREEN_DEFAULT 0 43 #define FULLSCREEN_DEFAULT 0
67 #define romseek gzseek 72 #define romseek gzseek
68 #define romgetc gzgetc 73 #define romgetc gzgetc
69 #define romclose gzclose 74 #define romclose gzclose
70 #endif 75 #endif
71 76
77 uint16_t *process_smd_block(uint16_t *dst, uint8_t *src, size_t bytes)
78 {
79 for (uint8_t *low = src, *high = (src+bytes/2), *end = src+bytes; high < end; high++, low++) {
80 *(dst++) = *low << 8 | *high;
81 }
82 return dst;
83 }
84
72 int load_smd_rom(ROMFILE f, void **buffer) 85 int load_smd_rom(ROMFILE f, void **buffer)
73 { 86 {
74 uint8_t block[SMD_BLOCK_SIZE]; 87 uint8_t block[SMD_BLOCK_SIZE];
75 romseek(f, SMD_HEADER_SIZE, SEEK_SET); 88 romseek(f, SMD_HEADER_SIZE, SEEK_SET);
76 89
77 size_t filesize = 512 * 1024; 90 size_t filesize = 512 * 1024;
78 size_t readsize = 0; 91 size_t readsize = 0;
79 uint16_t *dst = malloc(filesize); 92 uint16_t *dst, *buf;
80 93 dst = buf = malloc(filesize);
94
81 95
82 size_t read; 96 size_t read;
83 do { 97 do {
84 if ((readsize + SMD_BLOCK_SIZE > filesize)) { 98 if ((readsize + SMD_BLOCK_SIZE > filesize)) {
85 filesize *= 2; 99 filesize *= 2;
86 dst = realloc(dst, filesize); 100 buf = realloc(buf, filesize);
101 dst = buf + readsize/sizeof(uint16_t);
87 } 102 }
88 read = romread(block, 1, SMD_BLOCK_SIZE, f); 103 read = romread(block, 1, SMD_BLOCK_SIZE, f);
89 if (read > 0) { 104 if (read > 0) {
90 for (uint8_t *low = block, *high = (block+read/2), *end = block+read; high < end; high++, low++) { 105 dst = process_smd_block(dst, block, read);
91 *(dst++) = *low << 8 | *high;
92 }
93 readsize += read; 106 readsize += read;
94 } 107 }
95 } while(read > 0); 108 } while(read > 0);
96 romclose(f); 109 romclose(f);
97 110
98 *buffer = dst; 111 *buffer = buf;
99 112
100 return readsize; 113 return readsize;
101 } 114 }
102 115
116 uint8_t is_smd_format(const char *filename, uint8_t *header)
117 {
118 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) {
119 int i;
120 for (i = 3; i < 8; i++) {
121 if (header[i] != 0) {
122 return 0;
123 }
124 }
125 if (i == 8) {
126 if (header[2]) {
127 fatal_error("%s is a split SMD ROM which is not currently supported", filename);
128 }
129 return 1;
130 }
131 }
132 return 0;
133 }
134
103 uint32_t load_media_zip(const char *filename, system_media *dst) 135 uint32_t load_media_zip(const char *filename, system_media *dst)
104 { 136 {
105 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom"}; 137 static const char *valid_exts[] = {"bin", "md", "gen", "sms", "rom", "smd"};
106 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts); 138 const uint32_t num_exts = sizeof(valid_exts)/sizeof(*valid_exts);
107 zip_file *z = zip_open(filename); 139 zip_file *z = zip_open(filename);
108 if (!z) { 140 if (!z) {
109 return 0; 141 return 0;
110 } 142 }
111 143
112 for (uint32_t i = 0; i < z->num_entries; i++) 144 for (uint32_t i = 0; i < z->num_entries; i++)
113 { 145 {
114 char *ext = path_extension(z->entries[i].name); 146 char *ext = path_extension(z->entries[i].name);
115 if (!ext) { 147 if (!ext) {
116 continue; 148 continue;
119 { 151 {
120 if (!strcasecmp(ext, valid_exts[j])) { 152 if (!strcasecmp(ext, valid_exts[j])) {
121 size_t out_size = nearest_pow2(z->entries[i].size); 153 size_t out_size = nearest_pow2(z->entries[i].size);
122 dst->buffer = zip_read(z, i, &out_size); 154 dst->buffer = zip_read(z, i, &out_size);
123 if (dst->buffer) { 155 if (dst->buffer) {
156 if (is_smd_format(z->entries[i].name, dst->buffer)) {
157 size_t offset;
158 for (offset = 0; offset + SMD_BLOCK_SIZE + SMD_HEADER_SIZE <= out_size; offset += SMD_BLOCK_SIZE)
159 {
160 uint8_t tmp[SMD_BLOCK_SIZE];
161 uint8_t *u8dst = dst->buffer;
162 memcpy(tmp, u8dst + offset + SMD_HEADER_SIZE, SMD_BLOCK_SIZE);
163 process_smd_block((void *)(u8dst + offset), tmp, SMD_BLOCK_SIZE);
164 }
165 out_size = offset;
166 }
124 dst->extension = ext; 167 dst->extension = ext;
125 dst->dir = path_dirname(filename); 168 dst->dir = path_dirname(filename);
126 dst->name = basename_no_extension(filename); 169 dst->name = basename_no_extension(filename);
127 dst->size = out_size; 170 dst->size = out_size;
128 zip_close(z); 171 zip_close(z);
150 return 0; 193 return 0;
151 } 194 }
152 if (sizeof(header) != romread(header, 1, sizeof(header), f)) { 195 if (sizeof(header) != romread(header, 1, sizeof(header), f)) {
153 fatal_error("Error reading from %s\n", filename); 196 fatal_error("Error reading from %s\n", filename);
154 } 197 }
155 198
156 uint32_t ret = 0; 199 uint32_t ret = 0;
157 if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) { 200 if (is_smd_format(filename, header)) {
158 int i;
159 for (i = 3; i < 8; i++) {
160 if (header[i] != 0) {
161 break;
162 }
163 }
164 if (i == 8) {
165 if (header[2]) {
166 fatal_error("%s is a split SMD ROM which is not currently supported", filename);
167 }
168 if (stype) { 201 if (stype) {
169 *stype = SYSTEM_GENESIS; 202 *stype = SYSTEM_GENESIS;
170 } 203 }
171 ret = load_smd_rom(f, &dst->buffer); 204 ret = load_smd_rom(f, &dst->buffer);
172 } 205 }
173 } 206
174
175 if (!ret) { 207 if (!ret) {
176 size_t filesize = 512 * 1024; 208 size_t filesize = 512 * 1024;
177 size_t readsize = sizeof(header); 209 size_t readsize = sizeof(header);
178 210
179 char *buf = malloc(filesize); 211 char *buf = malloc(filesize);
180 memcpy(buf, header, readsize); 212 memcpy(buf, header, readsize);
181 213
182 size_t read; 214 size_t read;
183 do { 215 do {
184 read = romread(buf + readsize, 1, filesize - readsize, f); 216 read = romread(buf + readsize, 1, filesize - readsize, f);
185 if (read > 0) { 217 if (read > 0) {
186 readsize += read; 218 readsize += read;
201 } 233 }
202 dst->dir = path_dirname(filename); 234 dst->dir = path_dirname(filename);
203 dst->name = basename_no_extension(filename); 235 dst->name = basename_no_extension(filename);
204 dst->extension = path_extension(filename); 236 dst->extension = path_extension(filename);
205 dst->size = ret; 237 dst->size = ret;
206 238
207 romclose(f); 239 romclose(f);
208 return ret; 240 return ret;
209 } 241 }
210 242
211 243
245 char *savedir_template = tern_find_path(config, "ui\0save_path\0", TVAL_PTR).ptrval; 277 char *savedir_template = tern_find_path(config, "ui\0save_path\0", TVAL_PTR).ptrval;
246 if (!savedir_template) { 278 if (!savedir_template) {
247 savedir_template = "$USERDATA/blastem/$ROMNAME"; 279 savedir_template = "$USERDATA/blastem/$ROMNAME";
248 } 280 }
249 tern_node *vars = tern_insert_ptr(NULL, "ROMNAME", media->name); 281 tern_node *vars = tern_insert_ptr(NULL, "ROMNAME", media->name);
282 vars = tern_insert_ptr(vars, "ROMDIR", media->dir);
250 vars = tern_insert_ptr(vars, "HOME", get_home_dir()); 283 vars = tern_insert_ptr(vars, "HOME", get_home_dir());
251 vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir()); 284 vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir());
252 vars = tern_insert_ptr(vars, "USERDATA", (char *)get_userdata_dir()); 285 vars = tern_insert_ptr(vars, "USERDATA", (char *)get_userdata_dir());
253 char *save_dir = replace_vars(savedir_template, vars, 1); 286 char *save_dir = replace_vars(savedir_template, vars, 1);
254 tern_free(vars); 287 tern_free(vars);
256 warning("Failed to create save directory %s\n", save_dir); 289 warning("Failed to create save directory %s\n", save_dir);
257 } 290 }
258 return save_dir; 291 return save_dir;
259 } 292 }
260 293
294 const char *get_save_fname(uint8_t save_type)
295 {
296 switch(save_type)
297 {
298 case SAVE_I2C: return "save.eeprom";
299 case SAVE_NOR: return "save.nor";
300 case SAVE_HBPT: return "save.hbpt";
301 default: return "save.sram";
302 }
303 }
304
261 void setup_saves(system_media *media, system_header *context) 305 void setup_saves(system_media *media, system_header *context)
262 { 306 {
263 static uint8_t persist_save_registered; 307 static uint8_t persist_save_registered;
264 rom_info *info = &context->info; 308 rom_info *info = &context->info;
265 char *save_dir = get_save_dir(info->is_save_lock_on ? media->chain : media); 309 char *save_dir = get_save_dir(info->is_save_lock_on ? media->chain : media);
266 char const *parts[] = {save_dir, PATH_SEP, info->save_type == SAVE_I2C ? "save.eeprom" : info->save_type == SAVE_NOR ? "save.nor" : "save.sram"}; 310 char const *parts[] = {save_dir, PATH_SEP, get_save_fname(info->save_type)};
267 free(save_filename); 311 free(save_filename);
268 save_filename = alloc_concat_m(3, parts); 312 save_filename = alloc_concat_m(3, parts);
269 if (info->is_save_lock_on) { 313 if (info->is_save_lock_on) {
270 //initial save dir was calculated based on lock-on cartridge because that's where the save device is 314 //initial save dir was calculated based on lock-on cartridge because that's where the save device is
271 //save directory used for save states should still be located in the normal place 315 //save directory used for save states should still be located in the normal place
302 if (current_system) { 346 if (current_system) {
303 if (current_system->next_rom) { 347 if (current_system->next_rom) {
304 free(current_system->next_rom); 348 free(current_system->next_rom);
305 } 349 }
306 current_system->next_rom = strdup(filename); 350 current_system->next_rom = strdup(filename);
307 current_system->request_exit(current_system); 351 system_request_exit(current_system, 1);
308 if (menu_system && menu_system->type == SYSTEM_GENESIS) { 352 if (menu_system && menu_system->type == SYSTEM_GENESIS) {
309 genesis_context *gen = (genesis_context *)menu_system; 353 genesis_context *gen = (genesis_context *)menu_system;
310 if (gen->extra) { 354 if (gen->extra) {
311 menu_context *menu = gen->extra; 355 menu_context *menu = gen->extra;
312 menu->external_game_load = 1; 356 menu->external_game_load = 1;
321 } 365 }
322 #endif 366 #endif
323 } 367 }
324 368
325 static system_media cart, lock_on; 369 static system_media cart, lock_on;
370 const system_media *current_media(void)
371 {
372 return &cart;
373 }
374
326 void reload_media(void) 375 void reload_media(void)
327 { 376 {
328 if (!current_system) { 377 if (!current_system) {
329 return; 378 return;
330 } 379 }
338 int num_parts = parts[0] ? 5 : 3; 387 int num_parts = parts[0] ? 5 : 3;
339 if (!parts[4]) { 388 if (!parts[4]) {
340 num_parts--; 389 num_parts--;
341 } 390 }
342 current_system->next_rom = alloc_concat_m(num_parts, start); 391 current_system->next_rom = alloc_concat_m(num_parts, start);
343 current_system->request_exit(current_system); 392 system_request_exit(current_system, 1);
344 } 393 }
345 394
346 void lockon_media(char *lock_on_path) 395 void lockon_media(char *lock_on_path)
347 { 396 {
348 reload_media(); 397 reload_media();
374 free(cart.extension); 423 free(cart.extension);
375 system_type stype = SYSTEM_UNKNOWN; 424 system_type stype = SYSTEM_UNKNOWN;
376 if (!(cart.size = load_media(path, &cart, &stype))) { 425 if (!(cart.size = load_media(path, &cart, &stype))) {
377 fatal_error("Failed to open %s for reading\n", path); 426 fatal_error("Failed to open %s for reading\n", path);
378 } 427 }
379 428
380 if (force_stype != SYSTEM_UNKNOWN) { 429 if (force_stype != SYSTEM_UNKNOWN) {
381 stype = force_stype; 430 stype = force_stype;
382 } 431 }
383 if (stype == SYSTEM_UNKNOWN) { 432 if (stype == SYSTEM_UNKNOWN) {
384 stype = detect_system_type(&cart); 433 stype = detect_system_type(&cart);
395 menu_system->next_context = game_system; 444 menu_system->next_context = game_system;
396 } 445 }
397 game_system->next_context = menu_system; 446 game_system->next_context = menu_system;
398 setup_saves(&cart, game_system); 447 setup_saves(&cart, game_system);
399 update_title(game_system->info.name); 448 update_title(game_system->info.name);
449 }
450
451 char *parse_addr_port(char *arg)
452 {
453 while (*arg && *arg != ':') {
454 ++arg;
455 }
456 if (!*arg) {
457 return NULL;
458 }
459 char *end;
460 int port = strtol(arg + 1, &end, 10);
461 if (port && !*end) {
462 *arg = 0;
463 return arg + 1;
464 }
465 return NULL;
400 } 466 }
401 467
402 int main(int argc, char ** argv) 468 int main(int argc, char ** argv)
403 { 469 {
404 set_exe_str(argv[0]); 470 set_exe_str(argv[0]);
408 int debug = 0; 474 int debug = 0;
409 int loaded = 0; 475 int loaded = 0;
410 system_type stype = SYSTEM_UNKNOWN, force_stype = SYSTEM_UNKNOWN; 476 system_type stype = SYSTEM_UNKNOWN, force_stype = SYSTEM_UNKNOWN;
411 char * romfname = NULL; 477 char * romfname = NULL;
412 char * statefile = NULL; 478 char * statefile = NULL;
479 char *reader_addr = NULL, *reader_port = NULL;
480 event_reader reader = {0};
413 debugger_type dtype = DEBUGGER_NATIVE; 481 debugger_type dtype = DEBUGGER_NATIVE;
414 uint8_t start_in_debugger = 0; 482 uint8_t start_in_debugger = 0;
415 uint8_t fullscreen = FULLSCREEN_DEFAULT, use_gl = 1; 483 uint8_t fullscreen = FULLSCREEN_DEFAULT, use_gl = 1;
416 uint8_t debug_target = 0; 484 uint8_t debug_target = 0;
485 char *port;
417 for (int i = 1; i < argc; i++) { 486 for (int i = 1; i < argc; i++) {
418 if (argv[i][0] == '-') { 487 if (argv[i][0] == '-') {
419 switch(argv[i][1]) { 488 switch(argv[i][1]) {
420 case 'b': 489 case 'b':
421 i++; 490 i++;
434 break; 503 break;
435 case 'D': 504 case 'D':
436 gdb_remote_init(); 505 gdb_remote_init();
437 dtype = DEBUGGER_GDB; 506 dtype = DEBUGGER_GDB;
438 start_in_debugger = 1; 507 start_in_debugger = 1;
508 break;
509 case 'e':
510 i++;
511 if (i >= argc) {
512 fatal_error("-e must be followed by a file name\n");
513 }
514 port = parse_addr_port(argv[i]);
515 if (port) {
516 event_log_tcp(argv[i], port);
517 } else {
518 event_log_file(argv[i]);
519 }
439 break; 520 break;
440 case 'f': 521 case 'f':
441 fullscreen = !fullscreen; 522 fullscreen = !fullscreen;
442 break; 523 break;
443 case 'g': 524 case 'g':
519 " -d Enter debugger on startup\n" 600 " -d Enter debugger on startup\n"
520 " -n Disable Z80\n" 601 " -n Disable Z80\n"
521 " -v Display version number and exit\n" 602 " -v Display version number and exit\n"
522 " -l Log 68K code addresses (useful for assemblers)\n" 603 " -l Log 68K code addresses (useful for assemblers)\n"
523 " -y Log individual YM-2612 channels to WAVE files\n" 604 " -y Log individual YM-2612 channels to WAVE files\n"
605 " -e FILE Write hardware event log to FILE\n"
524 ); 606 );
525 return 0; 607 return 0;
526 default: 608 default:
527 fatal_error("Unrecognized switch %s\n", argv[i]); 609 fatal_error("Unrecognized switch %s\n", argv[i]);
528 } 610 }
529 } else if (!loaded) { 611 } else if (!loaded) {
612 reader_port = parse_addr_port(argv[i]);
613 if (reader_port) {
614 reader_addr = argv[i];
615 } else {
530 if (!load_media(argv[i], &cart, stype == SYSTEM_UNKNOWN ? &stype : NULL)) { 616 if (!load_media(argv[i], &cart, stype == SYSTEM_UNKNOWN ? &stype : NULL)) {
531 fatal_error("Failed to open %s for reading\n", argv[i]); 617 fatal_error("Failed to open %s for reading\n", argv[i]);
618 }
532 } 619 }
533 romfname = argv[i]; 620 romfname = argv[i];
534 loaded = 1; 621 loaded = 1;
535 } else if (width < 0) { 622 } else if (width < 0) {
536 width = atoi(argv[i]); 623 width = atoi(argv[i]);
537 } else if (height < 0) { 624 } else if (height < 0) {
538 height = atoi(argv[i]); 625 height = atoi(argv[i]);
539 } 626 }
540 } 627 }
541 628
542 int def_width = 0, def_height = 0; 629 int def_width = 0, def_height = 0;
543 char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval; 630 char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval;
544 if (config_width) { 631 if (config_width) {
545 def_width = atoi(config_width); 632 def_width = atoi(config_width);
546 } 633 }
560 char *config_fullscreen = tern_find_path(config, "video\0fullscreen\0", TVAL_PTR).ptrval; 647 char *config_fullscreen = tern_find_path(config, "video\0fullscreen\0", TVAL_PTR).ptrval;
561 if (config_fullscreen && !strcmp("on", config_fullscreen)) { 648 if (config_fullscreen && !strcmp("on", config_fullscreen)) {
562 fullscreen = !fullscreen; 649 fullscreen = !fullscreen;
563 } 650 }
564 if (!headless) { 651 if (!headless) {
652 if (reader_addr) {
653 render_set_external_sync(1);
654 }
565 render_init(width, height, "BlastEm", fullscreen); 655 render_init(width, height, "BlastEm", fullscreen);
566 render_set_drag_drop_handler(on_drag_drop); 656 render_set_drag_drop_handler(on_drag_drop);
567 } 657 }
568 set_bindings(); 658 set_bindings();
569 659
570 uint8_t menu = !loaded; 660 uint8_t menu = !loaded;
571 uint8_t use_nuklear = 0; 661 uint8_t use_nuklear = 0;
572 #ifndef DISABLE_NUKLEAR 662 #ifndef DISABLE_NUKLEAR
573 use_nuklear = !headless && is_nuklear_available(); 663 use_nuklear = !headless && is_nuklear_available();
574 #endif 664 #endif
605 use_native_states = 0; 695 use_native_states = 0;
606 } else if (state_format && strcmp(state_format, "native")) { 696 } else if (state_format && strcmp(state_format, "native")) {
607 warning("%s is not a valid value for the ui.state_format setting. Valid values are gst and native\n", state_format); 697 warning("%s is not a valid value for the ui.state_format setting. Valid values are gst and native\n", state_format);
608 } 698 }
609 699
610 if (loaded) { 700 if (loaded && !reader_addr) {
611 if (stype == SYSTEM_UNKNOWN) { 701 if (stype == SYSTEM_UNKNOWN) {
612 stype = detect_system_type(&cart); 702 stype = detect_system_type(&cart);
613 } 703 }
614 if (stype == SYSTEM_UNKNOWN) { 704 if (stype == SYSTEM_UNKNOWN) {
615 fatal_error("Failed to detect system type for %s\n", romfname); 705 fatal_error("Failed to detect system type for %s\n", romfname);
616 } 706 }
707
617 current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region); 708 current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region);
618 if (!current_system) { 709 if (!current_system) {
619 fatal_error("Failed to configure emulated machine for %s\n", romfname); 710 fatal_error("Failed to configure emulated machine for %s\n", romfname);
620 } 711 }
621 712
622 setup_saves(&cart, current_system); 713 setup_saves(&cart, current_system);
623 update_title(current_system->info.name); 714 update_title(current_system->info.name);
624 if (menu) { 715 if (menu) {
625 menu_system = current_system; 716 menu_system = current_system;
626 } else { 717 } else {
627 game_system = current_system; 718 game_system = current_system;
628 } 719 }
629 } 720 }
630 721
631 #ifndef DISABLE_NUKLEAR 722 #ifndef DISABLE_NUKLEAR
632 if (use_nuklear) { 723 if (use_nuklear) {
633 blastem_nuklear_init(!menu); 724 blastem_nuklear_init(!menu);
634 current_system = game_system; 725 current_system = game_system;
635 menu = 0; 726 menu = 0;
636 } 727 }
637 #endif 728 #endif
638 729
730 if (reader_addr) {
731 init_event_reader_tcp(&reader, reader_addr, reader_port);
732 stype = reader_system_type(&reader);
733 if (stype == SYSTEM_UNKNOWN) {
734 fatal_error("Failed to detect system type for %s\n", romfname);
735 }
736 game_system = current_system = alloc_config_player(stype, &reader);
737 //free inflate stream as it was inflateCopied to an internal event reader in the player
738 inflateEnd(&reader.input_stream);
739 setup_saves(&cart, current_system);
740 update_title(current_system->info.name);
741 }
742
639 current_system->debugger_type = dtype; 743 current_system->debugger_type = dtype;
640 current_system->enter_debugger = start_in_debugger && menu == debug_target; 744 current_system->enter_debugger = start_in_debugger && menu == debug_target;
641 current_system->start_context(current_system, menu ? NULL : statefile); 745 current_system->start_context(current_system, menu ? NULL : statefile);
746 render_video_loop();
642 for(;;) 747 for(;;)
643 { 748 {
644 if (current_system->should_exit) { 749 if (current_system->should_exit) {
645 break; 750 break;
646 } 751 }
652 menu = 0; 757 menu = 0;
653 current_system = game_system; 758 current_system = game_system;
654 current_system->debugger_type = dtype; 759 current_system->debugger_type = dtype;
655 current_system->enter_debugger = start_in_debugger && menu == debug_target; 760 current_system->enter_debugger = start_in_debugger && menu == debug_target;
656 current_system->start_context(current_system, statefile); 761 current_system->start_context(current_system, statefile);
762 render_video_loop();
657 } else if (menu && game_system) { 763 } else if (menu && game_system) {
658 current_system->arena = set_current_arena(game_system->arena); 764 current_system->arena = set_current_arena(game_system->arena);
659 current_system = game_system; 765 current_system = game_system;
660 menu = 0; 766 menu = 0;
661 current_system->resume_context(current_system); 767 current_system->resume_context(current_system);
669 current_system = menu_system; 775 current_system = menu_system;
670 menu = 1; 776 menu = 1;
671 } 777 }
672 if (!current_system->next_rom) { 778 if (!current_system->next_rom) {
673 current_system->resume_context(current_system); 779 current_system->resume_context(current_system);
780 render_video_loop();
674 } 781 }
675 } else { 782 } else {
676 break; 783 break;
677 } 784 }
678 } 785 }