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 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);

View File

@ -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)

View File

@ -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};

View File

@ -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