Input capturing semantic.

This commit is contained in:
Themaister 2011-06-11 20:02:17 +02:00
parent 45727bf9f5
commit 99e85684db
5 changed files with 116 additions and 11 deletions

View File

@ -393,6 +393,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
{ {
char semantic_buf[64]; char semantic_buf[64];
char wram_buf[64]; char wram_buf[64];
char input_slot_buf[64];
char apuram_buf[64]; char apuram_buf[64];
char oam_buf[64]; char oam_buf[64];
char cgram_buf[64]; char cgram_buf[64];
@ -401,6 +402,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
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);
print_buf(input_slot_buf, "%s_input_slot", id);
print_buf(apuram_buf, "%s_apuram", id); print_buf(apuram_buf, "%s_apuram", id);
print_buf(oam_buf, "%s_oam", id); print_buf(oam_buf, "%s_oam", id);
print_buf(cgram_buf, "%s_cgram", id); print_buf(cgram_buf, "%s_cgram", id);
@ -445,7 +447,25 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
if (tracker_type != SSNES_STATE_PYTHON) if (tracker_type != SSNES_STATE_PYTHON)
{ {
#endif #endif
if (config_get_hex(conf, wram_buf, &addr)) unsigned input_slot = 0;
if (config_get_hex(conf, input_slot_buf, &input_slot))
{
switch (input_slot)
{
case 1:
ram_type = SSNES_STATE_INPUT_SLOT1;
break;
case 2:
ram_type = SSNES_STATE_INPUT_SLOT2;
break;
default:
SSNES_ERR("Invalid input slot for import.\n");
goto error;
}
}
else if (config_get_hex(conf, wram_buf, &addr))
ram_type = SSNES_STATE_WRAM; ram_type = SSNES_STATE_WRAM;
else if (config_get_hex(conf, apuram_buf, &addr)) else if (config_get_hex(conf, apuram_buf, &addr))
ram_type = SSNES_STATE_APURAM; ram_type = SSNES_STATE_APURAM;
@ -482,8 +502,9 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
case SSNES_STATE_CGRAM: case SSNES_STATE_CGRAM:
memtype = SNES_MEMORY_CGRAM; memtype = SNES_MEMORY_CGRAM;
break; break;
default: default:
break; memtype = SNES_MEMORY_WRAM;
} }
if (addr >= psnes_get_memory_size(memtype)) if (addr >= psnes_get_memory_size(memtype))

View File

@ -446,6 +446,7 @@ static bool get_import_value(xmlNodePtr ptr)
xmlChar *id = xmlGetProp(ptr, (const xmlChar*)"id"); xmlChar *id = xmlGetProp(ptr, (const xmlChar*)"id");
xmlChar *semantic = xmlGetProp(ptr, (const xmlChar*)"semantic"); xmlChar *semantic = xmlGetProp(ptr, (const xmlChar*)"semantic");
xmlChar *wram = xmlGetProp(ptr, (const xmlChar*)"wram"); xmlChar *wram = xmlGetProp(ptr, (const xmlChar*)"wram");
xmlChar *input = xmlGetProp(ptr, (const xmlChar*)"input_slot");
xmlChar *apuram = xmlGetProp(ptr, (const xmlChar*)"apuram"); xmlChar *apuram = xmlGetProp(ptr, (const xmlChar*)"apuram");
xmlChar *vram = xmlGetProp(ptr, (const xmlChar*)"vram"); xmlChar *vram = xmlGetProp(ptr, (const xmlChar*)"vram");
xmlChar *oam = xmlGetProp(ptr, (const xmlChar*)"oam"); xmlChar *oam = xmlGetProp(ptr, (const xmlChar*)"oam");
@ -487,7 +488,24 @@ static bool get_import_value(xmlNodePtr ptr)
if (tracker_type != SSNES_STATE_PYTHON) if (tracker_type != SSNES_STATE_PYTHON)
{ {
#endif #endif
if (wram) { addr = strtoul((const char*)wram, NULL, 16); ram_type = SSNES_STATE_WRAM; } if (input)
{
unsigned slot = strtoul((const char*)input, NULL, 0);
switch (slot)
{
case 1:
ram_type = SSNES_STATE_INPUT_SLOT1;
break;
case 2:
ram_type = SSNES_STATE_INPUT_SLOT2;
break;
default:
SSNES_ERR("Invalid input slot for import!\n");
goto error;
}
}
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; }
@ -521,7 +539,7 @@ static bool get_import_value(xmlNodePtr ptr)
break; break;
default: default:
break; memtype = SNES_MEMORY_WRAM;
} }
if (addr >= psnes_get_memory_size(memtype)) if (addr >= psnes_get_memory_size(memtype))
@ -544,6 +562,7 @@ static bool get_import_value(xmlNodePtr ptr)
if (id) xmlFree(id); if (id) xmlFree(id);
if (semantic) xmlFree(semantic); if (semantic) xmlFree(semantic);
if (wram) xmlFree(wram); if (wram) xmlFree(wram);
if (input) xmlFree(input);
if (apuram) xmlFree(apuram); if (apuram) xmlFree(apuram);
if (vram) xmlFree(vram); if (vram) xmlFree(vram);
if (oam) xmlFree(oam); if (oam) xmlFree(oam);
@ -555,6 +574,7 @@ error:
if (id) xmlFree(id); if (id) xmlFree(id);
if (semantic) xmlFree(semantic); if (semantic) xmlFree(semantic);
if (wram) xmlFree(wram); if (wram) xmlFree(wram);
if (input) xmlFree(input);
if (apuram) xmlFree(apuram); if (apuram) xmlFree(apuram);
if (vram) xmlFree(vram); if (vram) xmlFree(vram);
if (oam) xmlFree(oam); if (oam) xmlFree(oam);

View File

@ -20,6 +20,7 @@
#include <assert.h> #include <assert.h>
#include "strl.h" #include "strl.h"
#include "general.h" #include "general.h"
#include <libsnes.hpp>
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
#include "py_state/py_state.h" #include "py_state/py_state.h"
@ -29,6 +30,9 @@ struct snes_tracker_internal
{ {
char id[64]; char id[64];
bool is_input;
unsigned input_slot;
const uint16_t *input_ptr;
const uint8_t *ptr; const uint8_t *ptr;
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
py_state_t *py; py_state_t *py;
@ -39,10 +43,10 @@ struct snes_tracker_internal
enum snes_tracker_type type; enum snes_tracker_type type;
uint8_t prev[2]; uint32_t prev[2];
int frame_count; int frame_count;
int frame_count_prev; int frame_count_prev;
uint8_t old_value; uint32_t old_value;
int transition_count; int transition_count;
}; };
@ -51,6 +55,8 @@ struct snes_tracker
struct snes_tracker_internal *info; struct snes_tracker_internal *info;
unsigned info_elem; unsigned info_elem;
uint16_t input_state[2];
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
py_state_t *py; py_state_t *py;
#endif #endif
@ -110,6 +116,16 @@ snes_tracker_t* snes_tracker_init(const struct snes_tracker_info *info)
case SSNES_STATE_VRAM: case SSNES_STATE_VRAM:
tracker->info[i].ptr = info->vram; tracker->info[i].ptr = info->vram;
break; break;
case SSNES_STATE_INPUT_SLOT1:
tracker->info[i].input_ptr = &tracker->input_state[0];
tracker->info[i].input_slot = 0;
tracker->info[i].is_input = true;
break;
case SSNES_STATE_INPUT_SLOT2:
tracker->info[i].input_ptr = &tracker->input_state[1];
tracker->info[i].input_slot = 1;
tracker->info[i].is_input = true;
break;
default: default:
tracker->info[i].ptr = NULL; tracker->info[i].ptr = NULL;
@ -128,7 +144,7 @@ void snes_tracker_free(snes_tracker_t *tracker)
free(tracker); free(tracker);
} }
#define fetch() (info->ptr[info->addr] & info->mask) #define fetch() ((info->is_input ? info->input_ptr[info->input_slot] : info->ptr[info->addr]) & info->mask)
static void update_element( static void update_element(
struct snes_tracker_uniform *uniform, struct snes_tracker_uniform *uniform,
@ -193,10 +209,52 @@ static void update_element(
#undef fetch #undef fetch
// Updates 16-bit input in same format as SNES itself.
static void update_input(snes_tracker_t *tracker)
{
if (!driver.input_data)
return;
static const unsigned buttons[] = {
SNES_DEVICE_ID_JOYPAD_R,
SNES_DEVICE_ID_JOYPAD_L,
SNES_DEVICE_ID_JOYPAD_X,
SNES_DEVICE_ID_JOYPAD_A,
SNES_DEVICE_ID_JOYPAD_RIGHT,
SNES_DEVICE_ID_JOYPAD_LEFT,
SNES_DEVICE_ID_JOYPAD_DOWN,
SNES_DEVICE_ID_JOYPAD_UP,
SNES_DEVICE_ID_JOYPAD_START,
SNES_DEVICE_ID_JOYPAD_SELECT,
SNES_DEVICE_ID_JOYPAD_Y,
SNES_DEVICE_ID_JOYPAD_B
};
static const struct snes_keybind *binds[MAX_PLAYERS] = {
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]
};
uint16_t state[2] = {0};
for (unsigned i = 4; i < 16; i++)
{
state[0] |= (driver.input->input_state(driver.input_data, binds, SNES_PORT_1, SNES_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
state[1] |= (driver.input->input_state(driver.input_data, binds, SNES_PORT_2, SNES_DEVICE_JOYPAD, 0, buttons[i - 4]) ? 1 : 0) << i;
}
for (unsigned i = 0; i < 2; i++)
tracker->input_state[i] = state[i];
}
unsigned snes_get_uniform(snes_tracker_t *tracker, struct snes_tracker_uniform *uniforms, unsigned elem, unsigned frame_count) unsigned snes_get_uniform(snes_tracker_t *tracker, struct snes_tracker_uniform *uniforms, unsigned elem, unsigned frame_count)
{ {
unsigned elems = tracker->info_elem < elem ? tracker->info_elem : elem; unsigned elems = tracker->info_elem < elem ? tracker->info_elem : elem;
update_input(tracker);
for (unsigned i = 0; i < elems; i++) for (unsigned i = 0; i < elems; i++)
update_element(&uniforms[i], &tracker->info[i], frame_count); update_element(&uniforms[i], &tracker->info[i], frame_count);

View File

@ -43,7 +43,9 @@ enum snes_ram_type
SSNES_STATE_APURAM, SSNES_STATE_APURAM,
SSNES_STATE_OAM, SSNES_STATE_OAM,
SSNES_STATE_CGRAM, SSNES_STATE_CGRAM,
SSNES_STATE_VRAM SSNES_STATE_VRAM,
SSNES_STATE_INPUT_SLOT1,
SSNES_STATE_INPUT_SLOT2
}; };
struct snes_tracker_uniform_info struct snes_tracker_uniform_info

10
ssnes.c
View File

@ -295,9 +295,13 @@ static int16_t input_state(bool port, unsigned device, unsigned index, unsigned
} }
} }
const struct snes_keybind *binds[MAX_PLAYERS]; static const struct snes_keybind *binds[MAX_PLAYERS] = {
for (int i = 0; i < MAX_PLAYERS; i++) g_settings.input.binds[0],
binds[i] = g_settings.input.binds[i]; g_settings.input.binds[1],
g_settings.input.binds[2],
g_settings.input.binds[3],
g_settings.input.binds[4]
};
int16_t res = driver.input->input_state(driver.input_data, binds, port, device, index, id); int16_t res = driver.input->input_state(driver.input_data, binds, port, device, index, id);
if (g_extern.bsv_movie && !g_extern.bsv_movie_playback) if (g_extern.bsv_movie && !g_extern.bsv_movie_playback)