Add *_equal semantics.

This commit is contained in:
Themaister 2012-02-12 18:05:33 +01:00
parent 9c861f13be
commit 5aa6acf031
4 changed files with 66 additions and 48 deletions

View File

@ -527,6 +527,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
char cgram_buf[64]; char cgram_buf[64];
char vram_buf[64]; char vram_buf[64];
char mask_buf[64]; char mask_buf[64];
char equal_buf[64];
print_buf(semantic_buf, "%s_semantic", id); print_buf(semantic_buf, "%s_semantic", id);
print_buf(wram_buf, "%s_wram", 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(cgram_buf, "%s_cgram", id);
print_buf(vram_buf, "%s_vram", id); print_buf(vram_buf, "%s_vram", id);
print_buf(mask_buf, "%s_mask", id); print_buf(mask_buf, "%s_mask", id);
print_buf(equal_buf, "%s_equal", id);
char *semantic = NULL; char *semantic = NULL;
@ -644,15 +646,19 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
goto end; goto end;
} }
unsigned bitmask = 0; unsigned bitmask;
if (!config_get_hex(conf, mask_buf, &bitmask)) if (!config_get_hex(conf, mask_buf, &bitmask))
bitmask = 0; 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)); strlcpy(info[info_cnt].id, id, sizeof(info[info_cnt].id));
info[info_cnt].addr = addr; info[info_cnt].addr = addr;
info[info_cnt].type = tracker_type; info[info_cnt].type = tracker_type;
info[info_cnt].ram_type = ram_type; info[info_cnt].ram_type = ram_type;
info[info_cnt].mask = bitmask; info[info_cnt].mask = bitmask;
info[info_cnt].equal = bitequal;
info_cnt++; info_cnt++;
free(semantic); free(semantic);

View File

@ -464,6 +464,7 @@ static bool get_script(const char *path, xmlNodePtr ptr)
static bool get_import_value(xmlNodePtr ptr) static bool get_import_value(xmlNodePtr ptr)
{ {
bool ret = true;
if (gl_tracker_info_cnt >= MAX_VARIABLES) if (gl_tracker_info_cnt >= MAX_VARIABLES)
{ {
SSNES_ERR("Too many import variables ...\n"); 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 *oam = xmlGetProp(ptr, (const xmlChar*)"oam");
xmlChar *cgram = xmlGetProp(ptr, (const xmlChar*)"cgram"); xmlChar *cgram = xmlGetProp(ptr, (const xmlChar*)"cgram");
xmlChar *bitmask = xmlGetProp(ptr, (const xmlChar*)"mask"); xmlChar *bitmask = xmlGetProp(ptr, (const xmlChar*)"mask");
xmlChar *bitequal = xmlGetProp(ptr, (const xmlChar*)"equal");
unsigned memtype; unsigned memtype;
enum snes_tracker_type tracker_type; enum snes_tracker_type tracker_type;
enum snes_ram_type ram_type = SSNES_STATE_NONE; enum snes_ram_type ram_type = SSNES_STATE_NONE;
uint32_t addr = 0; uint32_t addr = 0;
unsigned mask_value = 0; unsigned mask_value = 0;
unsigned mask_equal = 0;
if (!semantic || !id) if (!semantic || !id)
{ {
SSNES_ERR("No semantic or ID for import value.\n"); 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 else
{ {
SSNES_ERR("Invalid semantic for import value.\n"); SSNES_ERR("Invalid semantic for import value.\n");
goto error; ret = false;
goto end;
} }
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
@ -531,18 +536,20 @@ static bool get_import_value(xmlNodePtr ptr)
default: default:
SSNES_ERR("Invalid input slot for import.\n"); 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 (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 (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 (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 (cgram) { addr = strtoul((const char*)cgram, NULL, 16); ram_type = SSNES_STATE_CGRAM; }
else else
{ {
SSNES_ERR("No RAM address specificed for import value.\n"); 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))) if ((memtype != -1u) && (addr >= psnes_get_memory_size(memtype)))
{ {
SSNES_ERR("Address out of bounds.\n"); SSNES_ERR("Address out of bounds.\n");
goto error; ret = false;
goto end;
} }
if (bitmask) if (bitmask)
mask_value = strtoul((const char*)bitmask, NULL, 16); 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)); 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].addr = addr;
gl_tracker_info[gl_tracker_info_cnt].type = tracker_type; 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].ram_type = ram_type;
gl_tracker_info[gl_tracker_info_cnt].mask = mask_value; gl_tracker_info[gl_tracker_info_cnt].mask = mask_value;
gl_tracker_info[gl_tracker_info_cnt].equal = mask_equal;
gl_tracker_info_cnt++; gl_tracker_info_cnt++;
end:
if (id) xmlFree(id); if (id) xmlFree(id);
if (semantic) xmlFree(semantic); if (semantic) xmlFree(semantic);
if (wram) xmlFree(wram); if (wram) xmlFree(wram);
@ -593,19 +605,8 @@ static bool get_import_value(xmlNodePtr ptr)
if (oam) xmlFree(oam); if (oam) xmlFree(oam);
if (cgram) xmlFree(cgram); if (cgram) xmlFree(cgram);
if (bitmask) xmlFree(bitmask); if (bitmask) xmlFree(bitmask);
return true; if (bitequal) xmlFree(bitequal);
return ret;
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;
} }
static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size) static unsigned get_xml_shaders(const char *path, struct shader_program *prog, size_t size)

View File

@ -37,7 +37,9 @@ struct snes_tracker_internal
#endif #endif
uint32_t addr; uint32_t addr;
unsigned mask; uint16_t mask;
uint16_t equal;
enum snes_tracker_type type; 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++) for (unsigned i = 0; i < info->info_elem; i++)
{ {
strlcpy(tracker->info[i].id, info->info[i].id, sizeof(tracker->info[i].id)); 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].addr = info->info[i].addr;
tracker->info[i].type = info->info[i].type; 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].mask = (info->info[i].mask == 0) ? 0xffff : info->info[i].mask;
tracker->info[i].equal = info->info[i].equal;
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
if (info->info[i].type == SSNES_STATE_PYTHON) if (info->info[i].type == SSNES_STATE_PYTHON)
@ -140,7 +143,21 @@ void snes_tracker_free(snes_tracker_t *tracker)
free(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( static void update_element(
struct snes_tracker_uniform *uniform, struct snes_tracker_uniform *uniform,
@ -152,40 +169,40 @@ static void update_element(
switch (info->type) switch (info->type)
{ {
case SSNES_STATE_CAPTURE: case SSNES_STATE_CAPTURE:
uniform->value = fetch(); uniform->value = fetch(info);
break; break;
case SSNES_STATE_CAPTURE_PREV: case SSNES_STATE_CAPTURE_PREV:
if (info->prev[0] != fetch()) if (info->prev[0] != fetch(info))
{ {
info->prev[1] = info->prev[0]; info->prev[1] = info->prev[0];
info->prev[0] = fetch(); info->prev[0] = fetch(info);
} }
uniform->value = info->prev[1]; uniform->value = info->prev[1];
break; break;
case SSNES_STATE_TRANSITION: 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; info->frame_count = frame_count;
} }
uniform->value = info->frame_count; uniform->value = info->frame_count;
break; break;
case SSNES_STATE_TRANSITION_COUNT: 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++; info->transition_count++;
} }
uniform->value = info->transition_count; uniform->value = info->transition_count;
break; break;
case SSNES_STATE_TRANSITION_PREV: 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_prev = info->frame_count;
info->frame_count = 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. // Updates 16-bit input in same format as SNES itself.
static void update_input(snes_tracker_t *tracker) 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_START,
SNES_DEVICE_ID_JOYPAD_SELECT, SNES_DEVICE_ID_JOYPAD_SELECT,
SNES_DEVICE_ID_JOYPAD_Y, 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[0],
g_settings.input.binds[1], 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}; uint16_t state[2] = {0};

View File

@ -55,7 +55,8 @@ struct snes_tracker_uniform_info
uint32_t addr; uint32_t addr;
enum snes_tracker_type type; enum snes_tracker_type type;
enum snes_ram_type ram_type; enum snes_ram_type ram_type;
unsigned mask; uint16_t mask;
uint16_t equal;
}; };
struct snes_tracker_info struct snes_tracker_info