summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2018-07-06 17:39:59 -0700
committerMichael Pavone <pavone@retrodev.com>2018-07-06 17:39:59 -0700
commit480b9bb35341fb64afbd0ab6e18b978b2cd6d4f8 (patch)
tree061bc36100397b99945c51a2010a506482fcccbd
parentaad75c86365b71d625a730a0d42c6537a9016feb (diff)
Update controller config when changed in UI without restart
-rw-r--r--backend.h38
-rw-r--r--blastem.c22
-rw-r--r--genesis.c21
-rw-r--r--genesis.h2
-rw-r--r--io.c60
-rw-r--r--memmap.h41
-rw-r--r--romdb.h3
-rw-r--r--sms.c29
-rw-r--r--sms.h2
-rw-r--r--system.c6
-rw-r--r--system.h4
11 files changed, 130 insertions, 98 deletions
diff --git a/backend.h b/backend.h
index c55b143..b227aca 100644
--- a/backend.h
+++ b/backend.h
@@ -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 {
diff --git a/blastem.c b/blastem.c
index bc94462..00183e7 100644
--- a/blastem.c
+++ b/blastem.c
@@ -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 {
diff --git a/genesis.c b/genesis.c
index 942ee38..b9b1668 100644
--- a/genesis.c
+++ b/genesis.c
@@ -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);
}
diff --git a/genesis.h b/genesis.h
index 1b221e1..2b3163e 100644
--- a/genesis.h
+++ b/genesis.h
@@ -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);
diff --git a/io.c b/io.c
index ec51cd4..f6b7cff 100644
--- a/io.c
+++ b/io.c
@@ -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_
diff --git a/romdb.h b/romdb.h
index fa38b84..252b182 100644
--- a/romdb.h
+++ b/romdb.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);
diff --git a/sms.c b/sms.c
index d373fc0..e413964 100644
--- a/sms.c
+++ b/sms.c
@@ -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;
diff --git a/sms.h b/sms.h
index 60448a7..9f17c0f 100644
--- a/sms.h
+++ b/sms.h
@@ -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_
diff --git a/system.c b/system.c
index ef7ce33..39dbec0 100644
--- a/system.c
+++ b/system.c
@@ -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;
diff --git a/system.h b/system.h
index f812c4a..0ba25e2 100644
--- a/system.h
+++ b/system.h
@@ -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_