diff options
author | Michael Pavone <pavone@retrodev.com> | 2018-07-06 17:39:59 -0700 |
---|---|---|
committer | Michael Pavone <pavone@retrodev.com> | 2018-07-06 17:39:59 -0700 |
commit | 480b9bb35341fb64afbd0ab6e18b978b2cd6d4f8 (patch) | |
tree | 061bc36100397b99945c51a2010a506482fcccbd | |
parent | aad75c86365b71d625a730a0d42c6537a9016feb (diff) |
Update controller config when changed in UI without restart
-rw-r--r-- | backend.h | 38 | ||||
-rw-r--r-- | blastem.c | 22 | ||||
-rw-r--r-- | genesis.c | 21 | ||||
-rw-r--r-- | genesis.h | 2 | ||||
-rw-r--r-- | io.c | 60 | ||||
-rw-r--r-- | memmap.h | 41 | ||||
-rw-r--r-- | romdb.h | 3 | ||||
-rw-r--r-- | sms.c | 29 | ||||
-rw-r--r-- | sms.h | 2 | ||||
-rw-r--r-- | system.c | 6 | ||||
-rw-r--r-- | system.h | 4 |
11 files changed, 130 insertions, 98 deletions
@@ -40,43 +40,7 @@ typedef struct deferred_addr { 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 { @@ -248,9 +248,10 @@ static char *get_save_dir(system_media *media) 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 setup_saves(system_media *media, rom_info *info, system_header *context) 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 @@ void init_system_with_media(const char *path, system_type force_stype) 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 @@ void init_system_with_media(const char *path, system_type force_stype) 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 @@ int main(int argc, char ** argv) 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 { @@ -1190,7 +1190,6 @@ static void free_genesis(system_header *system) 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 @@ static void free_genesis(system_header *system) 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 @@ static void keyboard_up(system_header *system, uint8_t scancode) 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 @@ genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on 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 @@ genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on 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 @@ genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_o 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 @@ genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_o 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); } @@ -62,7 +62,7 @@ struct genesis_context { 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); @@ -202,7 +202,7 @@ uint8_t io_has_keyboard(sega_io *io) 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 @@ void process_device(char * device_type, io_port * port) } 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 @@ void setup_io_devices(tern_node * config, rom_info *rom, sega_io *io) 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 @@ void setup_io_devices(tern_node * config, rom_info *rom, sega_io *io) } } } - } 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) { diff --git a/memmap.h b/memmap.h new file mode 100644 index 0000000..f3504b4 --- /dev/null +++ b/memmap.h @@ -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_ @@ -51,7 +51,7 @@ enum { typedef struct rom_info rom_info; -#include "backend.h" +#include "memmap.h" struct rom_info { char *name; @@ -88,6 +88,7 @@ char const *save_type_name(uint8_t save_type); //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); @@ -530,14 +530,20 @@ static void keyboard_up(system_header *system, uint8_t scancode) 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) +{ + 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) { - memset(info_out, 0, sizeof(*info_out)); 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 @@ sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t for 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 @@ sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t for 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_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t for 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; @@ -26,6 +26,6 @@ typedef struct { 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_ @@ -48,7 +48,7 @@ system_type detect_system_type(system_media *media) 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 @@ system_header *alloc_config_system(system_type stype, system_media *media, uint3 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; @@ -53,6 +53,8 @@ struct system_header { 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 @@ struct system_media { #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_ |