changeset 1397:89eb967fed72

Initial support for drag and drop. Some work needed for proper menu integration.
author Michael Pavone <pavone@retrodev.com>
date Wed, 14 Jun 2017 09:48:46 -0700
parents aca496957999
children 08116cb5ffaa
files blastem.c render.h render_sdl.c
diffstat 3 files changed, 40 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Mon Jun 12 21:12:28 2017 -0700
+++ b/blastem.c	Wed Jun 14 09:48:46 2017 -0700
@@ -172,6 +172,15 @@
 	}
 }
 
+static void on_drag_drop(const char *filename)
+{
+	if (current_system->next_rom) {
+		free(current_system->next_rom);
+	}
+	current_system->next_rom = strdup(filename);
+	current_system->request_exit(current_system);
+}
+
 int main(int argc, char ** argv)
 {
 	set_exe_str(argv[0]);
@@ -365,6 +374,7 @@
 	}
 	if (!headless) {
 		render_init(width, height, "BlastEm", fullscreen);
+		render_set_drag_drop_handler(on_drag_drop);
 	}
 
 	if (stype == SYSTEM_UNKNOWN) {
@@ -394,40 +404,43 @@
 		if (current_system->should_exit) {
 			break;
 		}
-		if (menu && menu_context->next_rom) {
+		if (current_system->next_rom) {
+			char *next_rom = current_system->next_rom;
+			current_system->next_rom = NULL;
 			if (game_context) {
 				game_context->persist_save(game_context);
 				//swap to game context arena and mark all allocated pages in it free
-				current_system->arena = set_current_arena(game_context->arena);
+				if (menu) {
+					current_system->arena = set_current_arena(game_context->arena);
+				}
 				mark_all_free();
 				game_context->free_context(game_context);
 			} else {
 				//start a new arena and save old one in suspended genesis context
 				current_system->arena = start_new_arena();
 			}
-			if (!(cart.size = load_rom(menu_context->next_rom, &cart.buffer, &stype))) {
-				fatal_error("Failed to open %s for reading\n", menu_context->next_rom);
+			if (!(cart.size = load_rom(next_rom, &cart.buffer, &stype))) {
+				fatal_error("Failed to open %s for reading\n", next_rom);
 			}
-			cart.name = basename_no_extension(menu_context->next_rom);
-			cart.extension = path_extension(menu_context->next_rom);
+			cart.name = basename_no_extension(next_rom);
+			cart.extension = path_extension(next_rom);
 			stype = force_stype;
 			if (stype == SYSTEM_UNKNOWN) {
 				stype = detect_system_type(&cart);
 			}
 			if (stype == SYSTEM_UNKNOWN) {
-				fatal_error("Failed to detect system type for %s\n", menu_context->next_rom);
+				fatal_error("Failed to detect system type for %s\n", next_rom);
 			}
-			//allocate new genesis context
+			//allocate new system context
 			game_context = alloc_config_system(stype, &cart, opts,force_region, &info);
 			if (!game_context) {
-				fatal_error("Failed to configure emulated machine for %s\n", menu_context->next_rom);
+				fatal_error("Failed to configure emulated machine for %s\n", next_rom);
 			}
 			menu_context->next_context = game_context;
 			game_context->next_context = menu_context;
-			setup_saves(menu_context->next_rom, &info, game_context);
+			setup_saves(next_rom, &info, game_context);
 			update_title(info.name);
-			free(menu_context->next_rom);
-			menu_context->next_rom = NULL;
+			free(next_rom);
 			menu = 0;
 			current_system = game_context;
 			current_system->debugger_type = dtype;
--- a/render.h	Mon Jun 12 21:12:28 2017 -0700
+++ b/render.h	Wed Jun 14 09:48:46 2017 -0700
@@ -69,6 +69,8 @@
 #define RENDER_NOT_MAPPED -2
 #define RENDER_NOT_PLUGGED_IN -3
 
+typedef void (*drop_handler)(const char *filename);
+
 uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b);
 void render_save_screenshot(char *path);
 uint32_t *render_get_framebuffer(uint8_t which, int *pitch);
@@ -88,6 +90,7 @@
 int render_width();
 int render_height();
 int render_fullscreen();
+void render_set_drag_drop_handler(drop_handler handler);
 void process_events();
 int32_t render_translate_input_name(int32_t controller, char *name, uint8_t is_axis);
 int32_t render_dpad_part(int32_t input);
--- a/render_sdl.c	Mon Jun 12 21:12:28 2017 -0700
+++ b/render_sdl.c	Wed Jun 14 09:48:46 2017 -0700
@@ -914,6 +914,12 @@
 	[SDL_SCANCODE_KP_PERIOD] = 0x71,
 };
 
+static drop_handler drag_drop_handler;
+void render_set_drag_drop_handler(drop_handler handler)
+{
+	drag_drop_handler = handler;
+}
+
 static int32_t handle_event(SDL_Event *event)
 {
 	switch (event->type) {
@@ -986,6 +992,12 @@
 			break;
 		}
 		break;
+	case SDL_DROPFILE:
+		if (drag_drop_handler) {
+			drag_drop_handler(event->drop.file);
+		}
+		SDL_free(event->drop.file);
+		break;
 	case SDL_QUIT:
 		puts("");
 		exit(0);