Skip to content

Commit

Permalink
Gyroscope support for test input driver and test screen in remote ret…
Browse files Browse the repository at this point in the history
…ropad
  • Loading branch information
zoltanvb committed Jun 24, 2024
1 parent 5d65ee6 commit 0684531
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 11 deletions.
101 changes: 93 additions & 8 deletions cores/libretro-net-retropad/net_retropad_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
#define KEYBOARD_OFFSET 1000
#define NETRETROPAD_SCREEN_PAD 0
#define NETRETROPAD_SCREEN_KEYBOARD 1
#define NETRETROPAD_SCREEN_SENSORS 2
#define EVENT_RATE 60

struct descriptor {
int device;
Expand All @@ -82,6 +84,9 @@ struct remote_joypad_message {

static bool keyboard_state[RETROK_LAST];
static bool keyboard_state_validated[RETROK_LAST];
static bool tiltSensorEnabled = false;
static bool gyroSensorEnabled = false;
static bool luxSensorEnabled = false;

static int s;
static int port;
Expand All @@ -97,6 +102,8 @@ static retro_audio_sample_batch_t NETRETROPAD_CORE_PREFIX(audio_batch_cb);
static retro_environment_t NETRETROPAD_CORE_PREFIX(environ_cb);
static retro_input_poll_t NETRETROPAD_CORE_PREFIX(input_poll_cb);
static retro_input_state_t NETRETROPAD_CORE_PREFIX(input_state_cb);
static retro_sensor_get_input_t NETRETROPAD_CORE_PREFIX(sensor_get_input_cb);
static retro_set_sensor_state_t NETRETROPAD_CORE_PREFIX(sensor_set_state_cb);

static uint16_t *frame_buf;

Expand Down Expand Up @@ -136,7 +143,7 @@ static struct descriptor *descriptors[] = {
&analog_button
};

static uint16_t analog_item_colors[32];
static uint16_t analog_item_colors[40];

static uint16_t combo_def[] =
{
Expand Down Expand Up @@ -367,7 +374,7 @@ static void draw_background(void)
/* Body is 255 * 142 within the 320 * 240 frame */
uint16_t *pixel = frame_buf + 49 * 320 + 32;

if (current_screen == NETRETROPAD_SCREEN_PAD)
if (current_screen == NETRETROPAD_SCREEN_PAD || current_screen == NETRETROPAD_SCREEN_SENSORS)
for (rle = 0; rle < sizeof(body); )
{
uint16_t color = 0;
Expand Down Expand Up @@ -405,6 +412,8 @@ static void flip_screen(void)
if (current_screen == NETRETROPAD_SCREEN_PAD)
current_screen = NETRETROPAD_SCREEN_KEYBOARD;
else if (current_screen == NETRETROPAD_SCREEN_KEYBOARD)
current_screen = NETRETROPAD_SCREEN_SENSORS;
else if (current_screen == NETRETROPAD_SCREEN_SENSORS)
current_screen = NETRETROPAD_SCREEN_PAD;
draw_background();
}
Expand Down Expand Up @@ -445,6 +454,13 @@ void NETRETROPAD_CORE_PREFIX(retro_deinit)(void)
free(descriptors[i]->value);
descriptors[i]->value = NULL;
}

if (NETRETROPAD_CORE_PREFIX(sensor_set_state_cb) && NETRETROPAD_CORE_PREFIX(sensor_get_input_cb))
{
NETRETROPAD_CORE_PREFIX(sensor_set_state_cb)(0, RETRO_SENSOR_ACCELEROMETER_DISABLE, EVENT_RATE);
NETRETROPAD_CORE_PREFIX(sensor_set_state_cb)(0, RETRO_SENSOR_GYROSCOPE_DISABLE, EVENT_RATE);
NETRETROPAD_CORE_PREFIX(sensor_set_state_cb)(0, RETRO_SENSOR_ILLUMINANCE_DISABLE, EVENT_RATE);
}
}

unsigned NETRETROPAD_CORE_PREFIX(retro_api_version)(void)
Expand Down Expand Up @@ -618,7 +634,7 @@ void NETRETROPAD_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
{ "net_retropad_ip_octet2", "IP address part 2; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" },
{ "net_retropad_ip_octet3", "IP address part 3; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" },
{ "net_retropad_ip_octet4", "IP address part 4; 0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|126|127|128|129|130|131|132|133|134|135|136|137|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|158|159|160|161|162|163|164|165|166|167|168|169|170|171|172|173|174|175|176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255" },
{ "net_retropad_screen", "Start screen; Retropad|Keyboard tester" },
{ "net_retropad_screen", "Start screen; Retropad|Keyboard tester|Sensor tester" },
{ "net_retropad_hide_analog_mismatch", "Hide mismatching analog button inputs; True|False" },
{ NULL, NULL },
};
Expand All @@ -638,6 +654,34 @@ void NETRETROPAD_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)

NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK, &kcb);

if (cb(RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE, &sensorInterface)) {

NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG,"[Remote RetroPad]: Sensor interface supported, enabling.\n");

NETRETROPAD_CORE_PREFIX(sensor_get_input_cb) = sensorInterface.get_sensor_input;
NETRETROPAD_CORE_PREFIX(sensor_set_state_cb) = sensorInterface.set_sensor_state;


if (NETRETROPAD_CORE_PREFIX(sensor_set_state_cb) && NETRETROPAD_CORE_PREFIX(sensor_get_input_cb)) {
if (NETRETROPAD_CORE_PREFIX(sensor_set_state_cb)(0, RETRO_SENSOR_ACCELEROMETER_ENABLE, EVENT_RATE)) {
tiltSensorEnabled = true;
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG,"[Remote RetroPad]: Tilt sensor enabled.\n");
}

if (NETRETROPAD_CORE_PREFIX(sensor_set_state_cb)(0, RETRO_SENSOR_GYROSCOPE_ENABLE, EVENT_RATE)) {
gyroSensorEnabled = true;
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG,"[Remote RetroPad]: Gyro sensor enabled.\n");
}

if (NETRETROPAD_CORE_PREFIX(sensor_set_state_cb)(0, RETRO_SENSOR_ILLUMINANCE_ENABLE, EVENT_RATE)) {
luxSensorEnabled = true;
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_DEBUG,"[Remote RetroPad]: Lux sensor enabled.\n");
}
}
}


/* TODO: query sensor interface, enable sensors - but maybe only if sensor screen is active? */
}

static void netretropad_check_variables(void)
Expand All @@ -662,9 +706,10 @@ static void netretropad_check_variables(void)
snprintf(server, sizeof(server), "%s.%s.%s.%s", var.value, var2.value, var3.value, var4.value);
port = atoi(port_var.value);

if (screen_var.value &&
((current_screen == NETRETROPAD_SCREEN_PAD && strstr(screen_var.value,"Keyboard")) ||
(current_screen == NETRETROPAD_SCREEN_KEYBOARD && strstr(screen_var.value,"Retropad"))))
while (screen_var.value && !(
(current_screen == NETRETROPAD_SCREEN_PAD && strstr(screen_var.value,"Retropad")) ||
(current_screen == NETRETROPAD_SCREEN_KEYBOARD && strstr(screen_var.value,"Keyboard")) ||
(current_screen == NETRETROPAD_SCREEN_SENSORS && strstr(screen_var.value,"Sensor"))))
flip_screen();
if (hide_a_var.value && strstr(hide_a_var.value,"True"))
hide_analog_mismatch = true;
Expand Down Expand Up @@ -779,6 +824,46 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
}
}

/* Accelerometer and gyroscope. */

/* if (tiltEnabled) {
tiltX = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_X) * -2e8f;
tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * 2e8f;
}
if (gyroEnabled) {
gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f;
}*/

for (i = 32; i <= 32+6; i++)
{
/* bitmap: x-- x- x+ x++ y-- y- y+ y++*/
/* default analog deadzone: 0.0 - increased for convenience to 0.1, default analog threshold: 0.5 */
/* Red gradient also calculated */
/*int offset = DESC_OFFSET(&analog, 0, RETRO_DEVICE_INDEX_ANALOG_LEFT, i);
if ( (int16_t)analog.value[offset] < -32768/2)
{
input_state |= 1 << (16 + i*8 + 0);
analog_item_colors[ 16 + i*8 + 0] = (uint16_t)((-1*((int16_t)analog.value[offset])-32768/2) /528) << 11;
}
else if ((int16_t)analog.value[offset] < -3276)
{
input_state |= 1 << (16 + i*8 + 1);
analog_item_colors[ 16 + i*8 + 1] = (uint16_t)((-1*((int16_t)analog.value[offset]) ) /528) << 11;
}
else if ((int16_t)analog.value[offset] > 32768/2)
{
input_state |= 1 << (16 + i*8 + 3);
analog_item_colors[ 16 + i*8 + 3] = (uint16_t)(( ((int16_t)analog.value[offset])-32768/2) /528) << 11;
}
else if ((int16_t)analog.value[offset] > 3276)
{
input_state |= 1 << (16 + i*8 + 2);
analog_item_colors[ 16 + i*8 + 2] = (uint16_t)(( ((int16_t)analog.value[offset]) ) /528) << 11;
}*/
}



/* Input test section start. */

/* Check for predefined combo inputs. */
Expand Down Expand Up @@ -817,8 +902,8 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_INFO,
"[Remote RetroPad]: Proceeding to test step %d at frame %d, next: %d\n",
current_test_step,current_frame,next_teststep_frame+INITIAL_FRAMES);
if((input_test_steps[current_test_step].expected_button < KEYBOARD_OFFSET && current_screen == NETRETROPAD_SCREEN_KEYBOARD) ||
(input_test_steps[current_test_step].expected_button >= KEYBOARD_OFFSET && current_screen == NETRETROPAD_SCREEN_PAD))
while((input_test_steps[current_test_step].expected_button < KEYBOARD_OFFSET && current_screen != NETRETROPAD_SCREEN_PAD) ||
(input_test_steps[current_test_step].expected_button >= KEYBOARD_OFFSET && current_screen != NETRETROPAD_SCREEN_KEYBOARD))
flip_screen();
}
else
Expand Down
115 changes: 112 additions & 3 deletions input/drivers/test_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,30 @@

#define INPUT_TEST_COMMAND_PRESS_KEY 1
#define INPUT_TEST_COMMAND_RELEASE_KEY 2
#define INPUT_TEST_COMMAND_SET_SENSOR_ACC_X 10
#define INPUT_TEST_COMMAND_SET_SENSOR_ACC_Y 11
#define INPUT_TEST_COMMAND_SET_SENSOR_ACC_Z 12
#define INPUT_TEST_COMMAND_SET_SENSOR_GYR_X 13
#define INPUT_TEST_COMMAND_SET_SENSOR_GYR_Y 14
#define INPUT_TEST_COMMAND_SET_SENSOR_GYR_Z 15

/* TODO/FIXME - static globals */
static uint16_t test_key_state[DEFAULT_MAX_PADS+1][RETROK_LAST];

typedef struct
{
float x;
float y;
float z;
} sensor_t;

typedef struct test_input
{
sensor_t accelerometer_state; /* float alignment */
sensor_t gyroscope_state; /* float alignment */
} test_input_t;

static test_input_t test_input_values;

typedef struct
{
Expand Down Expand Up @@ -326,7 +346,6 @@ static int16_t test_input_state(
}
break;


case RETRO_DEVICE_KEYBOARD:
if (id && id < RETROK_LAST)
return (test_key_state[DEFAULT_MAX_PADS][id]);
Expand Down Expand Up @@ -358,6 +377,21 @@ static void* test_input_init(const char *joypad_driver)
return (void*)-1;
}

static float test_input_unsigned_to_float_acc(unsigned i)
{
if (i>200)
return 0.0f;
return ((signed int)(100-i))/100.0f;
}

static float test_input_unsigned_to_float_gyro(unsigned i)
{
if (i>200)
return 0.0f;
return ((signed int)(100-i))/100.0f;
}


static void test_input_poll(void *data)
{
video_driver_state_t *video_st = video_state_get_ptr();
Expand Down Expand Up @@ -392,6 +426,50 @@ static void test_input_poll(void *data)
"[Test input driver]: Releasing keyboard button %d at frame %d\n",
input_test_steps[i].param_num, curr_frame);
}
else if(input_test_steps[i].action == INPUT_TEST_COMMAND_SET_SENSOR_ACC_X ||
input_test_steps[i].action == INPUT_TEST_COMMAND_SET_SENSOR_ACC_Y ||
input_test_steps[i].action == INPUT_TEST_COMMAND_SET_SENSOR_ACC_Z)
{
float setval = test_input_unsigned_to_float_acc(input_test_steps[i].param_num);
switch (input_test_steps[i].action)
{
case INPUT_TEST_COMMAND_SET_SENSOR_ACC_X:
test_input_values.accelerometer_state.x = setval;
break;
case INPUT_TEST_COMMAND_SET_SENSOR_ACC_Y:
test_input_values.accelerometer_state.y = setval;
break;
case INPUT_TEST_COMMAND_SET_SENSOR_ACC_Z:
test_input_values.accelerometer_state.z = setval;
break;
}
input_test_steps[i].handled = true;
RARCH_DBG(
"[Test input driver]: Setting accelerometer axis %d to %f at frame %d\n",
input_test_steps[i].action - INPUT_TEST_COMMAND_SET_SENSOR_ACC_X, setval, curr_frame);
}
else if(input_test_steps[i].action == INPUT_TEST_COMMAND_SET_SENSOR_GYR_X ||
input_test_steps[i].action == INPUT_TEST_COMMAND_SET_SENSOR_GYR_Y ||
input_test_steps[i].action == INPUT_TEST_COMMAND_SET_SENSOR_GYR_Z)
{
float setval = test_input_unsigned_to_float_gyro(input_test_steps[i].param_num);
switch (input_test_steps[i].action)
{
case INPUT_TEST_COMMAND_SET_SENSOR_GYR_X:
test_input_values.gyroscope_state.x = setval;
break;
case INPUT_TEST_COMMAND_SET_SENSOR_GYR_Y:
test_input_values.gyroscope_state.y = setval;
break;
case INPUT_TEST_COMMAND_SET_SENSOR_GYR_Z:
test_input_values.gyroscope_state.z = setval;
break;
}
input_test_steps[i].handled = true;
RARCH_DBG(
"[Test input driver]: Setting gyroscope axis %d to %f at frame %d\n",
input_test_steps[i].action - INPUT_TEST_COMMAND_SET_SENSOR_GYR_X, setval, curr_frame);
}
else
{
input_test_steps[i].handled = true;
Expand All @@ -405,6 +483,35 @@ static void test_input_poll(void *data)
}


static bool test_input_set_sensor_state(void *data, unsigned port,
enum retro_sensor_action action, unsigned event_rate)
{
return true;
}

static float test_input_get_sensor_input(void *data,
unsigned port, unsigned id)
{
switch (id)
{
case RETRO_SENSOR_ACCELEROMETER_X:
return test_input_values.accelerometer_state.x;
case RETRO_SENSOR_ACCELEROMETER_Y:
return test_input_values.accelerometer_state.y;
case RETRO_SENSOR_ACCELEROMETER_Z:
return test_input_values.accelerometer_state.z;
case RETRO_SENSOR_GYROSCOPE_X:
return test_input_values.gyroscope_state.x;
case RETRO_SENSOR_GYROSCOPE_Y:
return test_input_values.gyroscope_state.y;
case RETRO_SENSOR_GYROSCOPE_Z:
return test_input_values.gyroscope_state.z;
}

return 0.0f;
}


static uint64_t test_input_get_capabilities(void *data)
{
return
Expand All @@ -416,13 +523,15 @@ static uint64_t test_input_get_capabilities(void *data)
| (1 << RETRO_DEVICE_LIGHTGUN)*/;
}

/* TODO: sensor should be part of joypad driver (or rather, also part of joypad driver) */

input_driver_t input_test = {
test_input_init,
test_input_poll,
test_input_state,
test_input_free_input,
NULL,
NULL,
test_input_set_sensor_state,
test_input_get_sensor_input,
test_input_get_capabilities,
"test",
NULL, /* grab_mouse */
Expand Down

0 comments on commit 0684531

Please sign in to comment.