summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2015-11-13 22:56:59 -0800
committerMichael Pavone <pavone@retrodev.com>2015-11-13 22:56:59 -0800
commit62fdcbc92ba3c4a71742293d75d853c95eb5f3c7 (patch)
treedce685f5cf74848f6d6a85f93689cf8dec50e89b
parent802454482c2843234a19a06f6acce360e0be3d60 (diff)
Selecting a second game from the menu now works
-rw-r--r--blastem.c41
-rw-r--r--io.c5
-rw-r--r--io.h1
-rw-r--r--m68k_core.c7
-rw-r--r--m68k_core.h1
-rw-r--r--menu.c17
-rw-r--r--psg.c9
-rw-r--r--psg.h1
-rw-r--r--render.h1
-rwxr-xr-xrender_sdl.c12
-rw-r--r--util.c8
-rw-r--r--vdp.c25
-rw-r--r--vdp.h1
-rw-r--r--ym2612.c22
-rw-r--r--ym2612.h1
-rw-r--r--z80_to_x86.c7
-rw-r--r--z80_to_x86.h1
17 files changed, 131 insertions, 29 deletions
diff --git a/blastem.c b/blastem.c
index 354197f..9403f09 100644
--- a/blastem.c
+++ b/blastem.c
@@ -887,9 +887,20 @@ genesis_context *alloc_init_genesis(rom_info *rom, int fps, uint32_t ym_opts)
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 @@ int main(int argc, char ** argv)
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 @@ int main(int argc, char ** argv)
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 --git a/io.c b/io.c
index 0debbd2..6ac4bf9 100644
--- a/io.c
+++ b/io.c
@@ -742,6 +742,11 @@ void set_keybindings(io_port *ports)
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 --git a/io.h b/io.h
index b73be67..f4af306 100644
--- a/io.h
+++ b/io.h
@@ -57,6 +57,7 @@ enum {
};
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 --git a/m68k_core.c b/m68k_core.c
index 877327e..6a7283f 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -1005,6 +1005,13 @@ void m68k_reset(m68k_context * context)
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 --git a/m68k_core.h b/m68k_core.h
index 07a1fb0..8c8deb6 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -74,6 +74,7 @@ void resume_68k(m68k_context *context);
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 --git a/menu.c b/menu.c
index f8b1537..e50ce61 100644
--- a/menu.c
+++ b/menu.c
@@ -64,23 +64,23 @@ char *get_external_storage_path()
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 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
}
}
} 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 --git a/psg.c b/psg.c
index 33484ad..a33aa7c 100644
--- a/psg.c
+++ b/psg.c
@@ -24,6 +24,15 @@ void psg_init(psg_context * context, uint32_t sample_rate, uint32_t master_clock
}
}
+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 --git a/psg.h b/psg.h
index 46c07b0..03768aa 100644
--- a/psg.h
+++ b/psg.h
@@ -33,6 +33,7 @@ typedef struct {
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 --git a/render.h b/render.h
index e923c15..c9bc820 100644
--- a/render.h
+++ b/render.h
@@ -34,6 +34,7 @@ typedef struct {
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 --git a/render_sdl.c b/render_sdl.c
index 66f57a2..6f0819c 100755
--- a/render_sdl.c
+++ b/render_sdl.c
@@ -115,7 +115,7 @@ const GLushort element_data[] = {0, 1, 2, 3};
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 @@ GLuint load_shader(char * fname, GLenum shader_type)
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 @@ void render_alloc_surfaces(vdp_context * context)
#endif
}
+void render_free_surfaces(vdp_context *context)
+{
+ free(context->framebuf);
+}
+
char * caption = NULL;
static void render_quit()
diff --git a/util.c b/util.c
index 697ba1b..57a59a2 100644
--- a/util.c
+++ b/util.c
@@ -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 @@ char *read_bundled_file(char *name, long *sizeret)
}
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 --git a/vdp.c b/vdp.c
index 560d273..f03c516 100644
--- a/vdp.c
+++ b/vdp.c
@@ -140,6 +140,19 @@ void init_vdp_context(vdp_context * context, uint8_t region_pal)
}
}
+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 @@ void render_map_output(uint32_t line, int32_t col, vdp_context * context)
src |= DBG_HILIGHT;
colors += CRAM_SIZE*2;
}
-
+
uint32_t outpixel;
if (context->debug) {
outpixel = context->debugcolors[src];
@@ -949,7 +962,7 @@ void vdp_advance_line(vdp_context *context)
} 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 @@ void vdp_advance_line(vdp_context *context)
vdp_advance_line(context);\
}\
CHECK_LIMIT
-
+
#define SPRITE_RENDER_H40(slot) \
case slot:\
render_sprite_cells( context);\
@@ -1038,7 +1051,7 @@ void vdp_advance_line(vdp_context *context)
}\
}\
CHECK_ONLY
-
+
#define SPRITE_RENDER_H32(slot) \
case slot:\
render_sprite_cells( context);\
@@ -1051,7 +1064,7 @@ void vdp_advance_line(vdp_context *context)
}\
context->cycles += slot_cycles;\
CHECK_ONLY
-
+
void vdp_h40(vdp_context * context, uint32_t target_cycles)
{
@@ -1684,7 +1697,7 @@ uint16_t vdp_control_port_read(vdp_context * context)
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 --git a/vdp.h b/vdp.h
index 5627057..5b9288c 100644
--- a/vdp.h
+++ b/vdp.h
@@ -176,6 +176,7 @@ typedef struct {
} 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 --git a/ym2612.c b/ym2612.c
index 60da9de..1d08697 100644
--- a/ym2612.c
+++ b/ym2612.c
@@ -104,11 +104,15 @@ ym2612_context * log_context = NULL;
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_adjust_master_clock(ym2612_context * context, uint32_t master_clock)
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 @@ void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clo
}
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_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clo
}
}
+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 --git a/ym2612.h b/ym2612.h
index 3619e52..0e5b672 100644
--- a/ym2612.h
+++ b/ym2612.h
@@ -124,6 +124,7 @@ enum {
};
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 --git a/z80_to_x86.c b/z80_to_x86.c
index c373d1b..a114da3 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -2596,6 +2596,13 @@ void z80_run(z80_context * context, uint32_t target_cycle)
}
}
+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 --git a/z80_to_x86.h b/z80_to_x86.h
index 51da4b0..b21cdbf 100644
--- a/z80_to_x86.h
+++ b/z80_to_x86.h
@@ -88,6 +88,7 @@ typedef struct {
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);