changeset 884:252dfd29831d

Selecting a second game from the menu now works
author Michael Pavone <pavone@retrodev.com>
date Fri, 13 Nov 2015 22:56:59 -0800
parents 9f149f0e98b7
children e3f5ec336432
files blastem.c io.c io.h m68k_core.c m68k_core.h menu.c psg.c psg.h render.h render_sdl.c util.c vdp.c vdp.h ym2612.c ym2612.h z80_to_x86.c z80_to_x86.h
diffstat 17 files changed, 131 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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])
--- 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);
--- 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)
 {
--- 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);
--- 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;
--- 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)
--- 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);
--- 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);
--- 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()
--- 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);
--- 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)
--- 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);
--- 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
--- 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);
--- 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);
--- 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);