From 5aa6acf031d0334ea862016e2004636ff1f4745f Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 12 Feb 2012 18:05:33 +0100 Subject: [PATCH] Add *_equal semantics. --- gfx/shader_cg.c | 8 ++++++- gfx/shader_glsl.c | 45 ++++++++++++++++++------------------ gfx/snes_state.c | 58 +++++++++++++++++++++++++++-------------------- gfx/snes_state.h | 3 ++- 4 files changed, 66 insertions(+), 48 deletions(-) diff --git a/gfx/shader_cg.c b/gfx/shader_cg.c index b6bcf9e852..b511cda918 100644 --- a/gfx/shader_cg.c +++ b/gfx/shader_cg.c @@ -527,6 +527,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf) char cgram_buf[64]; char vram_buf[64]; char mask_buf[64]; + char equal_buf[64]; print_buf(semantic_buf, "%s_semantic", id); print_buf(wram_buf, "%s_wram", id); @@ -536,6 +537,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf) print_buf(cgram_buf, "%s_cgram", id); print_buf(vram_buf, "%s_vram", id); print_buf(mask_buf, "%s_mask", id); + print_buf(equal_buf, "%s_equal", id); char *semantic = NULL; @@ -644,15 +646,19 @@ static bool load_imports(const char *dir_path, config_file_t *conf) goto end; } - unsigned bitmask = 0; + unsigned bitmask; if (!config_get_hex(conf, mask_buf, &bitmask)) bitmask = 0; + unsigned bitequal; + if (!config_get_hex(conf, equal_buf, &bitequal)) + bitequal = 0; strlcpy(info[info_cnt].id, id, sizeof(info[info_cnt].id)); info[info_cnt].addr = addr; info[info_cnt].type = tracker_type; info[info_cnt].ram_type = ram_type; info[info_cnt].mask = bitmask; + info[info_cnt].equal = bitequal; info_cnt++; free(semantic); diff --git a/gfx/shader_glsl.c b/gfx/shader_glsl.c index c6c1714de8..ecc70afb3e 100644 --- a/gfx/shader_glsl.c +++ b/gfx/shader_glsl.c @@ -464,6 +464,7 @@ static bool get_script(const char *path, xmlNodePtr ptr) static bool get_import_value(xmlNodePtr ptr) { + bool ret = true; if (gl_tracker_info_cnt >= MAX_VARIABLES) { SSNES_ERR("Too many import variables ...\n"); @@ -479,17 +480,20 @@ static bool get_import_value(xmlNodePtr ptr) xmlChar *oam = xmlGetProp(ptr, (const xmlChar*)"oam"); xmlChar *cgram = xmlGetProp(ptr, (const xmlChar*)"cgram"); xmlChar *bitmask = xmlGetProp(ptr, (const xmlChar*)"mask"); + xmlChar *bitequal = xmlGetProp(ptr, (const xmlChar*)"equal"); unsigned memtype; enum snes_tracker_type tracker_type; enum snes_ram_type ram_type = SSNES_STATE_NONE; uint32_t addr = 0; unsigned mask_value = 0; + unsigned mask_equal = 0; if (!semantic || !id) { SSNES_ERR("No semantic or ID for import value.\n"); - goto error; + ret = false; + goto end; } @@ -510,7 +514,8 @@ static bool get_import_value(xmlNodePtr ptr) else { SSNES_ERR("Invalid semantic for import value.\n"); - goto error; + ret = false; + goto end; } #ifdef HAVE_PYTHON @@ -531,18 +536,20 @@ static bool get_import_value(xmlNodePtr ptr) default: SSNES_ERR("Invalid input slot for import.\n"); - goto error; + ret = false; + goto end; } } - else if (wram) { addr = strtoul((const char*)wram, NULL, 16); ram_type = SSNES_STATE_WRAM; } + else if (wram) { addr = strtoul((const char*)wram, NULL, 16); ram_type = SSNES_STATE_WRAM; } else if (apuram) { addr = strtoul((const char*)apuram, NULL, 16); ram_type = SSNES_STATE_APURAM; } - else if (vram) { addr = strtoul((const char*)vram, NULL, 16); ram_type = SSNES_STATE_VRAM; } - else if (oam) { addr = strtoul((const char*)oam, NULL, 16); ram_type = SSNES_STATE_OAM; } - else if (cgram) { addr = strtoul((const char*)cgram, NULL, 16); ram_type = SSNES_STATE_CGRAM; } + else if (vram) { addr = strtoul((const char*)vram, NULL, 16); ram_type = SSNES_STATE_VRAM; } + else if (oam) { addr = strtoul((const char*)oam, NULL, 16); ram_type = SSNES_STATE_OAM; } + else if (cgram) { addr = strtoul((const char*)cgram, NULL, 16); ram_type = SSNES_STATE_CGRAM; } else { SSNES_ERR("No RAM address specificed for import value.\n"); - goto error; + ret = false; + goto end; } } @@ -571,19 +578,24 @@ static bool get_import_value(xmlNodePtr ptr) if ((memtype != -1u) && (addr >= psnes_get_memory_size(memtype))) { SSNES_ERR("Address out of bounds.\n"); - goto error; + ret = false; + goto end; } if (bitmask) mask_value = strtoul((const char*)bitmask, NULL, 16); + if (bitequal) + mask_equal = strtoul((const char*)bitequal, NULL, 16); strlcpy(gl_tracker_info[gl_tracker_info_cnt].id, (const char*)id, sizeof(gl_tracker_info[0].id)); gl_tracker_info[gl_tracker_info_cnt].addr = addr; gl_tracker_info[gl_tracker_info_cnt].type = tracker_type; gl_tracker_info[gl_tracker_info_cnt].ram_type = ram_type; gl_tracker_info[gl_tracker_info_cnt].mask = mask_value; + gl_tracker_info[gl_tracker_info_cnt].equal = mask_equal; gl_tracker_info_cnt++; +end: if (id) xmlFree(id); if (semantic) xmlFree(semantic); if (wram) xmlFree(wram); @@ -593,19 +605,8 @@ static bool get_import_value(xmlNodePtr ptr) if (oam) xmlFree(oam); if (cgram) xmlFree(cgram); if (bitmask) xmlFree(bitmask); - return true; - -error: - if (id) xmlFree(id); - if (semantic) xmlFree(semantic); - if (wram) xmlFree(wram); - if (input) xmlFree(input); - if (apuram) xmlFree(apuram); - if (vram) xmlFree(vram); - if (oam) xmlFree(oam); - if (cgram) xmlFree(cgram); - if (bitmask) xmlFree(bitmask); - return false; + if (bitequal) xmlFree(bitequal); + return ret; } static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size) diff --git a/gfx/snes_state.c b/gfx/snes_state.c index 4c5cf9f2ae..7b49268274 100644 --- a/gfx/snes_state.c +++ b/gfx/snes_state.c @@ -37,7 +37,9 @@ struct snes_tracker_internal #endif uint32_t addr; - unsigned mask; + uint16_t mask; + + uint16_t equal; enum snes_tracker_type type; @@ -85,9 +87,10 @@ snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info) for (unsigned i = 0; i < info->info_elem; i++) { strlcpy(tracker->info[i].id, info->info[i].id, sizeof(tracker->info[i].id)); - tracker->info[i].addr = info->info[i].addr; - tracker->info[i].type = info->info[i].type; - tracker->info[i].mask = (info->info[i].mask == 0) ? -1u : info->info[i].mask; + tracker->info[i].addr = info->info[i].addr; + tracker->info[i].type = info->info[i].type; + tracker->info[i].mask = (info->info[i].mask == 0) ? 0xffff : info->info[i].mask; + tracker->info[i].equal = info->info[i].equal; #ifdef HAVE_PYTHON if (info->info[i].type == SSNES_STATE_PYTHON) @@ -140,7 +143,21 @@ void snes_tracker_free(snes_tracker_t *tracker) free(tracker); } -#define fetch() ((info->is_input ? *info->input_ptr : info->ptr[info->addr]) & info->mask) +static inline uint16_t fetch(const struct snes_tracker_internal *info) +{ + uint16_t val = 0; + if (info->is_input) + val = *info->input_ptr; + else + val = info->ptr[info->addr]; + + val &= info->mask; + + if (info->equal && val != info->equal) + val = 0; + + return val; +} static void update_element( struct snes_tracker_uniform *uniform, @@ -152,40 +169,40 @@ static void update_element( switch (info->type) { case SSNES_STATE_CAPTURE: - uniform->value = fetch(); + uniform->value = fetch(info); break; case SSNES_STATE_CAPTURE_PREV: - if (info->prev[0] != fetch()) + if (info->prev[0] != fetch(info)) { info->prev[1] = info->prev[0]; - info->prev[0] = fetch(); + info->prev[0] = fetch(info); } uniform->value = info->prev[1]; break; case SSNES_STATE_TRANSITION: - if (info->old_value != fetch()) + if (info->old_value != fetch(info)) { - info->old_value = fetch(); + info->old_value = fetch(info); info->frame_count = frame_count; } uniform->value = info->frame_count; break; case SSNES_STATE_TRANSITION_COUNT: - if (info->old_value != fetch()) + if (info->old_value != fetch(info)) { - info->old_value = fetch(); + info->old_value = fetch(info); info->transition_count++; } uniform->value = info->transition_count; break; case SSNES_STATE_TRANSITION_PREV: - if (info->old_value != fetch()) + if (info->old_value != fetch(info)) { - info->old_value = fetch(); + info->old_value = fetch(info); info->frame_count_prev = info->frame_count; info->frame_count = frame_count; } @@ -203,8 +220,6 @@ static void update_element( } } -#undef fetch - // Updates 16-bit input in same format as SNES itself. static void update_input(snes_tracker_t *tracker) { @@ -223,18 +238,13 @@ static void update_input(snes_tracker_t *tracker) SNES_DEVICE_ID_JOYPAD_START, SNES_DEVICE_ID_JOYPAD_SELECT, SNES_DEVICE_ID_JOYPAD_Y, - SNES_DEVICE_ID_JOYPAD_B + SNES_DEVICE_ID_JOYPAD_B, }; - static const struct snes_keybind *binds[MAX_PLAYERS] = { + // Only bind for up to two players for now. + static const struct snes_keybind *binds[2] = { g_settings.input.binds[0], g_settings.input.binds[1], - g_settings.input.binds[2], - g_settings.input.binds[3], - g_settings.input.binds[4], - g_settings.input.binds[5], - g_settings.input.binds[6], - g_settings.input.binds[7], }; uint16_t state[2] = {0}; diff --git a/gfx/snes_state.h b/gfx/snes_state.h index 30ffa5ad14..fd2efba669 100644 --- a/gfx/snes_state.h +++ b/gfx/snes_state.h @@ -55,7 +55,8 @@ struct snes_tracker_uniform_info uint32_t addr; enum snes_tracker_type type; enum snes_ram_type ram_type; - unsigned mask; + uint16_t mask; + uint16_t equal; }; struct snes_tracker_info