changeset 1595:360d5bab199f

Update controller config when changed in UI without restart
author Michael Pavone <pavone@retrodev.com>
date Fri, 06 Jul 2018 17:39:59 -0700
parents 137dbd05ceab
children 437e80a700aa
files backend.h blastem.c genesis.c genesis.h io.c memmap.h romdb.h sms.c sms.h system.c system.h
diffstat 11 files changed, 130 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/backend.h	Fri Jun 29 09:33:23 2018 -0700
+++ b/backend.h	Fri Jul 06 17:39:59 2018 -0700
@@ -40,43 +40,7 @@
 	uint32_t             address;
 } deferred_addr;
 
-typedef enum {
-	READ_16,
-	READ_8,
-	WRITE_16,
-	WRITE_8
-} ftype;
-
-#define MMAP_READ      0x01
-#define MMAP_WRITE     0x02
-#define MMAP_CODE      0x04
-#define MMAP_PTR_IDX   0x08
-#define MMAP_ONLY_ODD  0x10
-#define MMAP_ONLY_EVEN 0x20
-#define MMAP_FUNC_NULL 0x40
-#define MMAP_BYTESWAP  0x80
-#define MMAP_AUX_BUFF  0x100
-#define MMAP_READ_CODE 0x200
-
-typedef uint16_t (*read_16_fun)(uint32_t address, void * context);
-typedef uint8_t (*read_8_fun)(uint32_t address, void * context);
-typedef void * (*write_16_fun)(uint32_t address, void * context, uint16_t value);
-typedef void * (*write_8_fun)(uint32_t address, void * context, uint8_t value);
-
-typedef struct {
-	uint32_t     start;
-	uint32_t     end;
-	uint32_t     mask;
-	uint32_t     aux_mask;
-	uint16_t     ptr_index;
-	uint16_t     flags;
-	void *       buffer;
-	read_16_fun  read_16;
-	write_16_fun write_16;
-	read_8_fun   read_8;
-	write_8_fun  write_8;
-} memmap_chunk;
-
+#include "memmap.h"
 #include "system.h"
 
 typedef struct {
--- a/blastem.c	Fri Jun 29 09:33:23 2018 -0700
+++ b/blastem.c	Fri Jul 06 17:39:59 2018 -0700
@@ -248,9 +248,10 @@
 	return save_dir;
 }
 
-void setup_saves(system_media *media, rom_info *info, system_header *context)
+void setup_saves(system_media *media, system_header *context)
 {
 	static uint8_t persist_save_registered;
+	rom_info *info = &context->info;
 	char *save_dir = get_save_dir(info->is_save_lock_on ? media->chain : media);
 	char const *parts[] = {save_dir, PATH_SEP, info->save_type == SAVE_I2C ? "save.eeprom" : info->save_type == SAVE_NOR ? "save.nor" : "save.sram"};
 	free(save_filename);
@@ -281,6 +282,9 @@
 void apply_updated_config(void)
 {
 	render_config_updated();
+	if (current_system && current_system->config_updated) {
+		current_system->config_updated(current_system);
+	}
 }
 
 static void on_drag_drop(const char *filename)
@@ -377,9 +381,8 @@
 	if (stype == SYSTEM_UNKNOWN) {
 		fatal_error("Failed to detect system type for %s\n", path);
 	}
-	rom_info info;
 	//allocate new system context
-	game_system = alloc_config_system(stype, &cart, opts, force_region, &info);
+	game_system = alloc_config_system(stype, &cart, opts, force_region);
 	if (!game_system) {
 		fatal_error("Failed to configure emulated machine for %s\n", path);
 	}
@@ -387,9 +390,8 @@
 		menu_system->next_context = game_system;
 	}
 	game_system->next_context = menu_system;
-	setup_saves(&cart, &info, game_system);
-	update_title(info.name);
-	free(info.name);
+	setup_saves(&cart, game_system);
+	update_title(game_system->info.name);
 }
 
 int main(int argc, char ** argv)
@@ -613,15 +615,13 @@
 		if (stype == SYSTEM_UNKNOWN) {
 			fatal_error("Failed to detect system type for %s\n", romfname);
 		}
-		rom_info info;
-		current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region, &info);
+		current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region);
 		if (!current_system) {
 			fatal_error("Failed to configure emulated machine for %s\n", romfname);
 		}
 	
-		setup_saves(&cart, &info, current_system);
-		update_title(info.name);
-		free(info.name);
+		setup_saves(&cart, current_system);
+		update_title(current_system->info.name);
 		if (menu) {
 			menu_system = current_system;
 		} else {
--- a/genesis.c	Fri Jun 29 09:33:23 2018 -0700
+++ b/genesis.c	Fri Jul 06 17:39:59 2018 -0700
@@ -1190,7 +1190,6 @@
 	vdp_free(gen->vdp);
 	memmap_chunk *map = (memmap_chunk *)gen->m68k->options->gen.memmap;
 	m68k_options_free(gen->m68k->options);
-	free(map);//needs to happen after m68k_options_free as that function uses the memory map
 	free(gen->cart);
 	free(gen->m68k);
 	free(gen->work_ram);
@@ -1199,8 +1198,8 @@
 	free(gen->zram);
 	ym_free(gen->ym);
 	psg_free(gen->psg);
-	free(gen->save_storage);
 	free(gen->header.save_dir);
+	free_rom_info(&gen->header.info);
 	free(gen->lock_on);
 	free(gen);
 }
@@ -1253,6 +1252,12 @@
 	io_keyboard_up(&gen->io, scancode);
 }
 
+static void config_updated(system_header *system)
+{
+	genesis_context *gen = (genesis_context *)system;
+	setup_io_devices(config, &system->info, &gen->io);
+}
+
 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region)
 {
 	static memmap_chunk z80_map[] = {
@@ -1283,7 +1288,9 @@
 	gen->header.mouse_motion_relative = mouse_motion_relative;
 	gen->header.keyboard_down = keyboard_down;
 	gen->header.keyboard_up = keyboard_up;
+	gen->header.config_updated = config_updated;
 	gen->header.type = SYSTEM_GENESIS;
+	gen->header.info = *rom;
 	set_region(gen, rom, force_region);
 
 	gen->vdp = malloc(sizeof(vdp_context));
@@ -1406,7 +1413,7 @@
 	return gen;
 }
 
-genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region, rom_info *info_out)
+genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region)
 {
 	static memmap_chunk base_map[] = {
 		{0xE00000, 0x1000000, 0xFFFF,   0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL,
@@ -1422,9 +1429,9 @@
 	if (!rom_db) {
 		rom_db = load_rom_db();
 	}
-	*info_out = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
-	rom = info_out->rom;
-	rom_size = info_out->rom_size;
+	rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
+	rom = info.rom;
+	rom_size = info.rom_size;
 #ifndef BLASTEM_BIG_ENDIAN
 	byteswap_rom(rom_size, rom);
 	if (lock_on) {
@@ -1439,5 +1446,5 @@
 	if (!MCLKS_PER_68K) {
 		MCLKS_PER_68K = 7;
 	}
-	return alloc_init_genesis(info_out, rom, lock_on, ym_opts, force_region);
+	return alloc_init_genesis(&info, rom, lock_on, ym_opts, force_region);
 }
--- a/genesis.h	Fri Jun 29 09:33:23 2018 -0700
+++ b/genesis.h	Fri Jul 06 17:39:59 2018 -0700
@@ -62,7 +62,7 @@
 
 uint16_t read_dma_value(uint32_t address);
 m68k_context * sync_components(m68k_context *context, uint32_t address);
-genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t system_opts, uint8_t force_region, rom_info *info_out);
+genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t system_opts, uint8_t force_region);
 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc);
 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen);
 
--- a/io.c	Fri Jun 29 09:33:23 2018 -0700
+++ b/io.c	Fri Jul 06 17:39:59 2018 -0700
@@ -202,7 +202,7 @@
 
 void process_device(char * device_type, io_port * port)
 {
-	port->device_type = IO_NONE;
+	//assuming that the io_port struct has been zeroed if this is the first time this has been called
 	if (!device_type)
 	{
 		return;
@@ -227,32 +227,42 @@
 		}
 		port->device.pad.gamepad_num = device_type[gamepad_len+2] - '0';
 	} else if(!strncmp(device_type, "mouse", mouse_len)) {
-		port->device_type = IO_MOUSE;
-		port->device.mouse.mouse_num = device_type[mouse_len+1] - '0';
-		port->device.mouse.last_read_x = 0;
-		port->device.mouse.last_read_y = 0;
-		port->device.mouse.cur_x = 0;
-		port->device.mouse.cur_y = 0;
-		port->device.mouse.latched_x = 0;
-		port->device.mouse.latched_y = 0;
-		port->device.mouse.ready_cycle = CYCLE_NEVER;
-		port->device.mouse.tr_counter = 0;
+		if (port->device_type != IO_MOUSE) {
+			port->device_type = IO_MOUSE;
+			port->device.mouse.mouse_num = device_type[mouse_len+1] - '0';
+			port->device.mouse.last_read_x = 0;
+			port->device.mouse.last_read_y = 0;
+			port->device.mouse.cur_x = 0;
+			port->device.mouse.cur_y = 0;
+			port->device.mouse.latched_x = 0;
+			port->device.mouse.latched_y = 0;
+			port->device.mouse.ready_cycle = CYCLE_NEVER;
+			port->device.mouse.tr_counter = 0;
+		}
 	} else if(!strcmp(device_type, "saturn keyboard")) {
-		port->device_type = IO_SATURN_KEYBOARD;
-		port->device.keyboard.read_pos = 0xFF;
-		port->device.keyboard.write_pos = 0;
+		if (port->device_type != IO_SATURN_KEYBOARD) {
+			port->device_type = IO_SATURN_KEYBOARD;
+			port->device.keyboard.read_pos = 0xFF;
+			port->device.keyboard.write_pos = 0;
+		}
 	} else if(!strcmp(device_type, "xband keyboard")) {
-		port->device_type = IO_XBAND_KEYBOARD;
-		port->device.keyboard.read_pos = 0xFF;
-		port->device.keyboard.write_pos = 0;
+		if (port->device_type != IO_XBAND_KEYBOARD) {
+			port->device_type = IO_XBAND_KEYBOARD;
+			port->device.keyboard.read_pos = 0xFF;
+			port->device.keyboard.write_pos = 0;
+		}
 	} else if(!strcmp(device_type, "sega_parallel")) {
-		port->device_type = IO_SEGA_PARALLEL;
-		port->device.stream.data_fd = -1;
-		port->device.stream.listen_fd = -1;
+		if (port->device_type != IO_SEGA_PARALLEL) {
+			port->device_type = IO_SEGA_PARALLEL;
+			port->device.stream.data_fd = -1;
+			port->device.stream.listen_fd = -1;
+		}
 	} else if(!strcmp(device_type, "generic")) {
-		port->device_type = IO_GENERIC;
-		port->device.stream.data_fd = -1;
-		port->device.stream.listen_fd = -1;
+		if (port->device_type != IO_GENERIC) {
+			port->device_type = IO_GENERIC;
+			port->device.stream.data_fd = -1;
+			port->device.stream.listen_fd = -1;
+		}
 	}
 }
 
@@ -308,7 +318,7 @@
 	for (int i = 0; i < 3; i++)
 	{
 #ifndef _WIN32
-		if (ports[i].device_type == IO_SEGA_PARALLEL)
+		if (ports[i].device_type == IO_SEGA_PARALLEL && ports[i].device.stream.data_fd == -1)
 		{
 			char *pipe_name = tern_find_path(config, "io\0parallel_pipe\0", TVAL_PTR).ptrval;
 			if (!pipe_name)
@@ -335,7 +345,7 @@
 					}
 				}
 			}
-		} else if (ports[i].device_type == IO_GENERIC) {
+		} else if (ports[i].device_type == IO_GENERIC && ports[i].device.stream.data_fd == -1) {
 			char *sock_name = tern_find_path(config, "io\0socket\0", TVAL_PTR).ptrval;
 			if (!sock_name)
 			{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memmap.h	Fri Jul 06 17:39:59 2018 -0700
@@ -0,0 +1,41 @@
+#ifndef MEMMAP_H_
+#define MEMMAP_H_
+
+typedef enum {
+	READ_16,
+	READ_8,
+	WRITE_16,
+	WRITE_8
+} ftype;
+
+#define MMAP_READ      0x01
+#define MMAP_WRITE     0x02
+#define MMAP_CODE      0x04
+#define MMAP_PTR_IDX   0x08
+#define MMAP_ONLY_ODD  0x10
+#define MMAP_ONLY_EVEN 0x20
+#define MMAP_FUNC_NULL 0x40
+#define MMAP_BYTESWAP  0x80
+#define MMAP_AUX_BUFF  0x100
+#define MMAP_READ_CODE 0x200
+
+typedef uint16_t (*read_16_fun)(uint32_t address, void * context);
+typedef uint8_t (*read_8_fun)(uint32_t address, void * context);
+typedef void * (*write_16_fun)(uint32_t address, void * context, uint16_t value);
+typedef void * (*write_8_fun)(uint32_t address, void * context, uint8_t value);
+
+typedef struct {
+	uint32_t     start;
+	uint32_t     end;
+	uint32_t     mask;
+	uint32_t     aux_mask;
+	uint16_t     ptr_index;
+	uint16_t     flags;
+	void *       buffer;
+	read_16_fun  read_16;
+	write_16_fun write_16;
+	read_8_fun   read_8;
+	write_8_fun  write_8;
+} memmap_chunk;
+
+#endif //MEMMAP_H_
--- a/romdb.h	Fri Jun 29 09:33:23 2018 -0700
+++ b/romdb.h	Fri Jul 06 17:39:59 2018 -0700
@@ -51,7 +51,7 @@
 
 typedef struct rom_info rom_info;
 
-#include "backend.h"
+#include "memmap.h"
 
 struct rom_info {
 	char          *name;
@@ -88,6 +88,7 @@
 //Note: free_rom_info only frees things pointed to by a rom_info struct, not the struct itself
 //this is because rom_info structs are typically stack allocated
 void free_rom_info(rom_info *info);
+typedef struct system_header system_header;
 void cart_serialize(system_header *sys, serialize_buffer *buf);
 void cart_deserialize(deserialize_buffer *buf, void *vcontext);
 
--- a/sms.c	Fri Jun 29 09:33:23 2018 -0700
+++ b/sms.c	Fri Jul 06 17:39:59 2018 -0700
@@ -530,14 +530,20 @@
 	io_keyboard_up(&sms->io, scancode);
 }
 
-sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info_out)
+static void config_updated(system_header *system)
 {
-	memset(info_out, 0, sizeof(*info_out));
+	sms_context *sms = (sms_context *)system;
+	setup_io_devices(config, &system->info, &sms->io);
+}
+
+
+sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region)
+{
 	sms_context *sms = calloc(1, sizeof(sms_context));
 	uint32_t rom_size = nearest_pow2(media->size);
 	memmap_chunk memory_map[6];
 	if (media->size > 0xC000)  {
-		info_out->map_chunks = 6;
+		sms->header.info.map_chunks = 6;
 		uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4;
 		memory_map[0] = (memmap_chunk){0x0000, 0x0400,  0xFFFF,             0, 0, MMAP_READ,                        media->buffer, NULL, NULL, NULL, NULL};
 		memory_map[1] = (memmap_chunk){0x0400, 0x4000,  0xFFFF,             0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL,     NULL, NULL, NULL, NULL};
@@ -546,21 +552,21 @@
 		memory_map[4] = (memmap_chunk){0xC000, 0xFFFC,  sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE,   sms->ram, NULL, NULL, NULL, NULL};
 		memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0x0003,             0, 0, MMAP_READ,                        ram_reg_overlap, NULL, NULL, NULL, mapper_write};
 	} else {
-		info_out->map_chunks = 2;
+		sms->header.info.map_chunks = 2;
 		memory_map[0] = (memmap_chunk){0x0000, 0xC000,  rom_size-1,         0, 0, MMAP_READ,                      media->buffer,  NULL, NULL, NULL, NULL};
 		memory_map[1] = (memmap_chunk){0xC000, 0x10000, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
 	};
-	info_out->map = malloc(sizeof(memmap_chunk) * info_out->map_chunks);
-	memcpy(info_out->map, memory_map, sizeof(memmap_chunk) * info_out->map_chunks);
+	sms->header.info.map = malloc(sizeof(memmap_chunk) * sms->header.info.map_chunks);
+	memcpy(sms->header.info.map, memory_map, sizeof(memmap_chunk) * sms->header.info.map_chunks);
 	z80_options *zopts = malloc(sizeof(z80_options));
-	init_z80_opts(zopts, info_out->map, info_out->map_chunks, io_map, 4, 15, 0xFF);
+	init_z80_opts(zopts, sms->header.info.map, sms->header.info.map_chunks, io_map, 4, 15, 0xFF);
 	sms->z80 = init_z80_context(zopts);
 	sms->z80->system = sms;
 	sms->z80->options->gen.debug_cmd_handler = debug_commands;
 	
 	sms->rom = media->buffer;
 	sms->rom_size = rom_size;
-	if (info_out->map_chunks > 2) {
+	if (sms->header.info.map_chunks > 2) {
 		sms->z80->mem_pointers[0] = sms->rom;
 		sms->z80->mem_pointers[1] = sms->rom + 0x4000;
 		sms->z80->mem_pointers[2] = sms->rom + 0x8000;
@@ -579,10 +585,10 @@
 	init_vdp_context(sms->vdp, 0);
 	sms->vdp->system = &sms->header;
 	
-	info_out->save_type = SAVE_NONE;
-	info_out->name = strdup(media->name);
+	sms->header.info.save_type = SAVE_NONE;
+	sms->header.info.name = strdup(media->name);
 	
-	setup_io_devices(config, info_out, &sms->io);
+	setup_io_devices(config, &sms->header.info, &sms->io);
 	sms->header.has_keyboard = io_has_keyboard(&sms->io);
 	
 	sms->header.set_speed_percent = set_speed_percent;
@@ -605,6 +611,7 @@
 	sms->header.mouse_motion_relative = mouse_motion_relative;
 	sms->header.keyboard_down = keyboard_down;
 	sms->header.keyboard_up = keyboard_up;
+	sms->header.config_updated = config_updated;
 	sms->header.type = SYSTEM_SMS;
 	
 	return sms;
--- a/sms.h	Fri Jun 29 09:33:23 2018 -0700
+++ b/sms.h	Fri Jul 06 17:39:59 2018 -0700
@@ -26,6 +26,6 @@
 	uint8_t       cart_ram[SMS_CART_RAM_SIZE];
 } sms_context;
 
-sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info_out);
+sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t force_region);
 
 #endif //SMS_H_
--- a/system.c	Fri Jun 29 09:33:23 2018 -0700
+++ b/system.c	Fri Jul 06 17:39:59 2018 -0700
@@ -48,7 +48,7 @@
 	return SYSTEM_UNKNOWN;
 }
 
-system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region, rom_info *info_out)
+system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region)
 {
 	void *lock_on = NULL;
 	uint32_t lock_on_size = 0;
@@ -59,10 +59,10 @@
 	switch (stype)
 	{
 	case SYSTEM_GENESIS:
-		return &(alloc_config_genesis(media->buffer, media->size, lock_on, lock_on_size, opts, force_region, info_out))->header;
+		return &(alloc_config_genesis(media->buffer, media->size, lock_on, lock_on_size, opts, force_region))->header;
 #ifndef NO_Z80
 	case SYSTEM_SMS:
-		return &(alloc_configure_sms(media, opts, force_region, info_out))->header;
+		return &(alloc_configure_sms(media, opts, force_region))->header;
 #endif
 	default:
 		return NULL;
--- a/system.h	Fri Jun 29 09:33:23 2018 -0700
+++ b/system.h	Fri Jul 06 17:39:59 2018 -0700
@@ -53,6 +53,8 @@
 	system_mrel_fun   mouse_motion_relative;
 	system_u8_fun     keyboard_down;
 	system_u8_fun     keyboard_up;
+	system_fun        config_updated;
+	rom_info          info;
 	arena             *arena;
 	char              *next_rom;
 	char              *save_dir;
@@ -77,6 +79,6 @@
 #define OPT_ADDRESS_LOG (1U << 31U)
 
 system_type detect_system_type(system_media *media);
-system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region, rom_info *info_out);
+system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region);
 
 #endif //SYSTEM_H_