# HG changeset patch # User Michael Pavone # Date 1447484219 28800 # Node ID 252dfd29831d628c77f33d2fa02ee6f7f523d22a # Parent 9f149f0e98b7ab0f8228ea00d40e5692432f5a6f Selecting a second game from the menu now works diff -r 9f149f0e98b7 -r 252dfd29831d blastem.c --- a/blastem.c Fri Nov 13 19:15:37 2015 -0800 +++ b/blastem.c Fri Nov 13 22:56:59 2015 -0800 @@ -887,9 +887,20 @@ return gen; } +void free_genesis(genesis_context *gen) +{ + vdp_free(gen->vdp); + m68k_options_free(gen->m68k->options); + free(gen->m68k); + z80_options_free(gen->z80->options); + free(gen->z80); + ym_free(gen->ym); + psg_free(gen->psg); + free(gen->save_storage); +} + void start_genesis(genesis_context *gen, char *statefile, uint8_t *debugger) { - set_keybindings(gen->ports); if (statefile) { uint32_t pc = load_gst(gen, statefile); @@ -1129,14 +1140,25 @@ game_context = genesis; } + set_keybindings(genesis->ports); start_genesis(genesis, menu ? NULL : statefile, menu ? NULL : debuggerfun); for(;;) { if (menu && menu_context->next_rom) { + if (game_context) { + if (game_context->save_type != SAVE_NONE) { + persist_save(); + } + free(game_context->cart); + free(save_filename); + base_map[0].buffer = ram = game_context->work_ram; + } else { + base_map[0].buffer = ram = malloc(RAM_WORDS * sizeof(uint16_t)); + } + memset(ram, 0, RAM_WORDS * sizeof(uint16_t)); if (!(rom_size = load_rom(menu_context->next_rom))) { fatal_error("Failed to open %s for reading\n", menu_context->next_rom); } - base_map[0].buffer = ram = malloc(RAM_WORDS * sizeof(uint16_t)); info = configure_rom(rom_db, cart, rom_size, base_map, sizeof(base_map)/sizeof(base_map[0])); byteswap_rom(rom_size); set_region(&info, force_version); @@ -1158,35 +1180,36 @@ if (!game_context) { //start a new arena and save old one in suspended genesis context genesis->arena = start_new_arena(); - //allocate new genesis context - game_context = alloc_init_genesis(&info, fps, ym_log ? YM_OPT_WAVE_LOG : 0); } else { - //TODO: hard reset of context with new ROM + genesis->arena = set_current_arena(game_context->arena); + mark_all_free(); + free_genesis(game_context); } + //allocate new genesis context + game_context = alloc_init_genesis(&info, fps, ym_log ? YM_OPT_WAVE_LOG : 0); free(menu_context->next_rom); menu_context->next_rom = NULL; menu = 0; genesis = game_context; genesis->m68k->options->address_log = address_log; + map_all_bindings(genesis->ports); start_genesis(genesis, statefile, debuggerfun); } else if (menu && game_context) { - puts("Switching back to game context"); genesis->arena = set_current_arena(game_context->arena); genesis = game_context; cart = genesis->cart; ram = genesis->work_ram; menu = 0; - set_keybindings(genesis->ports); + map_all_bindings(genesis->ports); resume_68k(genesis->m68k); } else if (!menu && menu_context) { - puts("Switching back to menu context"); genesis->arena = set_current_arena(menu_context->arena); genesis = menu_context; cart = genesis->cart; ram = genesis->work_ram; menu = 1; - set_keybindings(genesis->ports); + map_all_bindings(genesis->ports); resume_68k(genesis->m68k); } else { break; diff -r 9f149f0e98b7 -r 252dfd29831d io.c --- a/io.c Fri Nov 13 19:15:37 2015 -0800 +++ b/io.c Fri Nov 13 22:56:59 2015 -0800 @@ -742,6 +742,11 @@ speeds[i] = 100; } } + map_all_bindings(ports); +} + +void map_all_bindings(io_port *ports) +{ for (int bucket = 0; bucket < 256; bucket++) { if (bindings[bucket]) diff -r 9f149f0e98b7 -r 252dfd29831d io.h --- a/io.h Fri Nov 13 19:15:37 2015 -0800 +++ b/io.h Fri Nov 13 22:56:59 2015 -0800 @@ -57,6 +57,7 @@ }; void set_keybindings(io_port *ports); +void map_all_bindings(io_port *ports); void setup_io_devices(tern_node * config, io_port * ports); void io_adjust_cycles(io_port * pad, uint32_t current_cycle, uint32_t deduction); void io_data_write(io_port * pad, uint8_t value, uint32_t current_cycle); diff -r 9f149f0e98b7 -r 252dfd29831d m68k_core.c --- a/m68k_core.c Fri Nov 13 19:15:37 2015 -0800 +++ b/m68k_core.c Fri Nov 13 22:56:59 2015 -0800 @@ -1005,6 +1005,13 @@ start_68k_context(context, address); } +void m68k_options_free(m68k_options *opts) +{ + free(opts->gen.native_code_map); + free(opts->gen.ram_inst_sizes); + free(opts); +} + m68k_context * init_68k_context(m68k_options * opts) { diff -r 9f149f0e98b7 -r 252dfd29831d m68k_core.h --- a/m68k_core.h Fri Nov 13 19:15:37 2015 -0800 +++ b/m68k_core.h Fri Nov 13 22:56:59 2015 -0800 @@ -74,6 +74,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider); m68k_context * init_68k_context(m68k_options * opts); void m68k_reset(m68k_context * context); +void m68k_options_free(m68k_options *opts); void insert_breakpoint(m68k_context * context, uint32_t address, uint8_t * bp_handler); void remove_breakpoint(m68k_context * context, uint32_t address); m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context); diff -r 9f149f0e98b7 -r 252dfd29831d menu.c --- a/menu.c Fri Nov 13 19:15:37 2015 -0800 +++ b/menu.c Fri Nov 13 22:56:59 2015 -0800 @@ -64,23 +64,23 @@ if ((*env)->PushLocalFrame(env, 8) < 0) { return NULL; } - + jclass Environment = (*env)->FindClass(env, "android/os/Environment"); - jmethodID getExternalStorageDirectory = + jmethodID getExternalStorageDirectory = (*env)->GetStaticMethodID(env, Environment, "getExternalStorageDirectory", "()Ljava/io/File;"); jobject file = (*env)->CallStaticObjectMethod(env, Environment, getExternalStorageDirectory); if (!file) { goto cleanup; } - + jmethodID getAbsolutePath = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, file), "getAbsolutePath", "()Ljava/lang/String;"); jstring path = (*env)->CallObjectMethod(env, file, getAbsolutePath); - + char const *tmp = (*env)->GetStringUTFChars(env, path, NULL); ret = strdup(tmp); (*env)->ReleaseStringUTFChars(env, path, tmp); - + cleanup: (*env)->PopLocalFrame(env, NULL); return ret; @@ -173,16 +173,17 @@ } } } else { - char *pieces[] = {menu->curpath, "/", buf}; + char *tmp = menu->curpath; + char const *pieces[] = {menu->curpath, "/", buf}; menu->curpath = alloc_concat_m(3, pieces); - free(pieces[0]); + free(tmp); } break; } case 2: { char buf[4096]; copy_string_from_guest(m68k, dst, buf, sizeof(buf)); - char *pieces[] = {menu->curpath, "/", buf}; + char const *pieces[] = {menu->curpath, "/", buf}; gen->next_rom = alloc_concat_m(3, pieces); m68k->should_return = 1; break; diff -r 9f149f0e98b7 -r 252dfd29831d psg.c --- a/psg.c Fri Nov 13 19:15:37 2015 -0800 +++ b/psg.c Fri Nov 13 22:56:59 2015 -0800 @@ -24,6 +24,15 @@ } } +void psg_free(psg_context *context) +{ + free(context->audio_buffer); + //TODO: Figure out how to make this 100% safe + //audio thread could still be using this + free(context->back_buffer); + free(context); +} + #define BUFFER_INC_RES 1000000000UL void psg_adjust_master_clock(psg_context * context, uint32_t master_clock) diff -r 9f149f0e98b7 -r 252dfd29831d psg.h --- a/psg.h Fri Nov 13 19:15:37 2015 -0800 +++ b/psg.h Fri Nov 13 22:56:59 2015 -0800 @@ -33,6 +33,7 @@ void psg_init(psg_context * context, uint32_t sample_rate, uint32_t master_clock, uint32_t clock_div, uint32_t samples_frame); +void psg_free(psg_context *context); void psg_adjust_master_clock(psg_context * context, uint32_t master_clock); void psg_write(psg_context * context, uint8_t value); void psg_run(psg_context * context, uint32_t cycles); diff -r 9f149f0e98b7 -r 252dfd29831d render.h --- a/render.h Fri Nov 13 19:15:37 2015 -0800 +++ b/render.h Fri Nov 13 22:56:59 2015 -0800 @@ -34,6 +34,7 @@ uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b); void render_alloc_surfaces(vdp_context * context); +void render_free_surfaces(vdp_context *context); void render_init(int width, int height, char * title, uint32_t fps, uint8_t fullscreen); void render_update_caption(char *title); void render_context(vdp_context * context); diff -r 9f149f0e98b7 -r 252dfd29831d render_sdl.c --- a/render_sdl.c Fri Nov 13 19:15:37 2015 -0800 +++ b/render_sdl.c Fri Nov 13 22:56:59 2015 -0800 @@ -115,7 +115,7 @@ GLuint load_shader(char * fname, GLenum shader_type) { - char * parts[] = {get_home_dir(), "/.config/blastem/shaders/", fname}; + char const * parts[] = {get_home_dir(), "/.config/blastem/shaders/", fname}; char * shader_path = alloc_concat_m(3, parts); FILE * f = fopen(shader_path, "rb"); free(shader_path); @@ -158,10 +158,15 @@ void render_alloc_surfaces(vdp_context * context) { + static uint8_t texture_init; context->oddbuf = context->framebuf = malloc(512 * 256 * 4 * 2); memset(context->oddbuf, 0, 512 * 256 * 4 * 2); context->evenbuf = ((char *)context->oddbuf) + 512 * 256 * 4; + if (texture_init) { + return; + } + texture_init = 1; #ifndef DISABLE_OPENGL if (render_gl) { glGenTextures(3, textures); @@ -211,6 +216,11 @@ #endif } +void render_free_surfaces(vdp_context *context) +{ + free(context->framebuf); +} + char * caption = NULL; static void render_quit() diff -r 9f149f0e98b7 -r 252dfd29831d util.c --- a/util.c Fri Nov 13 19:15:37 2015 -0800 +++ b/util.c Fri Nov 13 22:56:59 2015 -0800 @@ -19,9 +19,9 @@ #define warning_printf(msg, args) __android_log_vprint(ANDROID_LOG_WARN, "BlastEm", msg, args) #define fatal_printf(msg, args) __android_log_vprint(ANDROID_LOG_FATAL, "BlastEm", msg, args) #else -#define info_puts(msg) fputs(stdout, msg); -#define warning_puts(msg) fputs(stderr, msg); -#define fatal_puts(msg) fputs(stderr, msg); +#define info_puts(msg) fputs(msg, stdout); +#define warning_puts(msg) fputs(msg, stderr); +#define fatal_puts(msg) fputs(msg, stderr); #define info_printf(msg, args) vprintf(msg, args) #define warning_printf(msg, args) vfprintf(stderr, msg, args) @@ -388,7 +388,7 @@ } return NULL; } - char *pieces[] = {exe_dir, "/", name}; + char const *pieces[] = {exe_dir, "/", name}; char *path = alloc_concat_m(3, pieces); FILE *f = fopen(path, "rb"); free(path); diff -r 9f149f0e98b7 -r 252dfd29831d vdp.c --- a/vdp.c Fri Nov 13 19:15:37 2015 -0800 +++ b/vdp.c Fri Nov 13 22:56:59 2015 -0800 @@ -140,6 +140,19 @@ } } +void vdp_free(vdp_context *context) +{ + free(context->vdpmem); + free(context->linebuf); + if (headless) { + free(context->oddbuf); + free(context->evenbuf); + } else { + render_free_surfaces(context); + } + free(context); +} + int is_refresh(vdp_context * context, uint32_t slot) { if (context->regs[REG_MODE_4] & BIT_H40) { @@ -847,7 +860,7 @@ src |= DBG_HILIGHT; colors += CRAM_SIZE*2; } - + uint32_t outpixel; if (context->debug) { outpixel = context->debugcolors[src]; @@ -949,7 +962,7 @@ } else if (!(context->latched_mode & BIT_PAL) && context->vcounter == 0xEB) { context->vcounter = 0x1E5; } - + if (context->vcounter > (context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START)) { context->hint_counter = context->regs[REG_HINT]; } else if (context->hint_counter) { @@ -1020,7 +1033,7 @@ vdp_advance_line(context);\ }\ CHECK_LIMIT - + #define SPRITE_RENDER_H40(slot) \ case slot:\ render_sprite_cells( context);\ @@ -1038,7 +1051,7 @@ }\ }\ CHECK_ONLY - + #define SPRITE_RENDER_H32(slot) \ case slot:\ render_sprite_cells( context);\ @@ -1051,7 +1064,7 @@ }\ context->cycles += slot_cycles;\ CHECK_ONLY - + void vdp_h40(vdp_context * context, uint32_t target_cycles) { @@ -1684,7 +1697,7 @@ line > inactive_start && line < 0x1FF ) - || (line == inactive_start + || (line == inactive_start && ( slot >= (context->regs[REG_MODE_4] & BIT_H40 ? VBLANK_START_H40 : VBLANK_START_H32) || slot < (context->regs[REG_MODE_4] & BIT_H40 ? LINE_CHANGE_H40 : LINE_CHANGE_H32) diff -r 9f149f0e98b7 -r 252dfd29831d vdp.h --- a/vdp.h Fri Nov 13 19:15:37 2015 -0800 +++ b/vdp.h Fri Nov 13 22:56:59 2015 -0800 @@ -176,6 +176,7 @@ } vdp_context; void init_vdp_context(vdp_context * context, uint8_t region_pal); +void vdp_free(vdp_context *context); void vdp_run_context(vdp_context * context, uint32_t target_cycles); //runs from current cycle count to VBLANK for the current mode, returns ending cycle count uint32_t vdp_run_to_vblank(vdp_context * context); diff -r 9f149f0e98b7 -r 252dfd29831d ym2612.c --- a/ym2612.c Fri Nov 13 19:15:37 2015 -0800 +++ b/ym2612.c Fri Nov 13 22:56:59 2015 -0800 @@ -104,11 +104,15 @@ void ym_finalize_log() { + if (!log_context) { + return; + } for (int i = 0; i < NUM_CHANNELS; i++) { if (log_context->channels[i].logfile) { wave_finalize(log_context->channels[i].logfile); } } + log_context = NULL; } #define BUFFER_INC_RES 1000000000UL @@ -124,6 +128,7 @@ void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clock, uint32_t clock_div, uint32_t sample_limit, uint32_t options) { + static uint8_t registered_finalize; dfopen(debug_file, "ym_debug.txt", "w"); memset(context, 0, sizeof(*context)); context->audio_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2); @@ -157,7 +162,10 @@ } if (options & YM_OPT_WAVE_LOG) { log_context = context; - atexit(ym_finalize_log); + if (!registered_finalize) { + atexit(ym_finalize_log); + registered_finalize = 1; + } } if (!did_tbl_init) { //populate sine table @@ -218,6 +226,18 @@ } } +void ym_free(ym2612_context *context) +{ + if (context == log_context) { + ym_finalize_log(); + } + free(context->audio_buffer); + //TODO: Figure out how to make this 100% safe + //audio thread could still be using this + free(context->back_buffer); + free(context); +} + #define YM_VOLUME_MULTIPLIER 2 #define YM_VOLUME_DIVIDER 3 #define YM_MOD_SHIFT 1 diff -r 9f149f0e98b7 -r 252dfd29831d ym2612.h --- a/ym2612.h Fri Nov 13 19:15:37 2015 -0800 +++ b/ym2612.h Fri Nov 13 22:56:59 2015 -0800 @@ -124,6 +124,7 @@ }; void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clock, uint32_t clock_div, uint32_t sample_limit, uint32_t options); +void ym_free(ym2612_context *context); void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock); void ym_run(ym2612_context * context, uint32_t to_cycle); void ym_address_write_part1(ym2612_context * context, uint8_t address); diff -r 9f149f0e98b7 -r 252dfd29831d z80_to_x86.c --- a/z80_to_x86.c Fri Nov 13 19:15:37 2015 -0800 +++ b/z80_to_x86.c Fri Nov 13 22:56:59 2015 -0800 @@ -2596,6 +2596,13 @@ } } +void z80_options_free(z80_options *opts) +{ + free(opts->gen.native_code_map); + free(opts->gen.ram_inst_sizes); + free(opts); +} + void z80_assert_reset(z80_context * context, uint32_t cycle) { z80_run(context, cycle); diff -r 9f149f0e98b7 -r 252dfd29831d z80_to_x86.h --- a/z80_to_x86.h Fri Nov 13 19:15:37 2015 -0800 +++ b/z80_to_x86.h Fri Nov 13 22:56:59 2015 -0800 @@ -88,6 +88,7 @@ void translate_z80_stream(z80_context * context, uint32_t address); void init_z80_opts(z80_options * options, memmap_chunk const * chunks, uint32_t num_chunks, memmap_chunk const * io_chunks, uint32_t num_io_chunks, uint32_t clock_divider); +void z80_options_free(z80_options *opts); void init_z80_context(z80_context * context, z80_options * options); code_ptr z80_get_native_address(z80_context * context, uint32_t address); code_ptr z80_get_native_address_trans(z80_context * context, uint32_t address);