Skip to content

Commit

Permalink
add option for not showing analog mismatch
Browse files Browse the repository at this point in the history
analog coloring for axes
enable option change on core restarts
  • Loading branch information
zoltanvb committed Mar 30, 2024
1 parent b51e5cf commit aee7797
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 60 deletions.
162 changes: 106 additions & 56 deletions cores/libretro-net-retropad/net_retropad_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ static struct descriptor *descriptors[] = {
&analog_button
};

static uint16_t analog_item_colors[32];

static uint16_t combo_def[] =
{
1 << RETRO_DEVICE_ID_JOYPAD_UP | 1 << RETRO_DEVICE_ID_JOYPAD_LEFT, /* D-pad diagonals */
Expand Down Expand Up @@ -172,7 +174,7 @@ static unsigned last_test_step = MAX_TEST_STEPS + 1;
static uint32_t input_state_validated = 0;
static uint32_t combo_state_validated = 0;
static bool dump_state_blocked = false;

static bool hide_analog_mismatch = true;
/************************************/
/* JSON Helpers for test input file */
/************************************/
Expand Down Expand Up @@ -560,7 +562,11 @@ static void retropad_update_input(void)
/* Update state */
desc->value[offset] = state;

/* Attempt to send updated state */
/* Do not send analog button state - RA side is not prepared to receive it */
if (i>1)
continue;

/* Otherwise, attempt to send updated state */
msg.port = port;
msg.device = desc->device;
msg.index = index;
Expand All @@ -575,6 +581,35 @@ static void retropad_update_input(void)
}
}

static void open_UDP_socket()
{
socket_target_t in_target;

if (s && s != SOCKET_ERROR)
close(s);

s = socket_create(
"retropad",
SOCKET_DOMAIN_INET,
SOCKET_TYPE_DATAGRAM,
SOCKET_PROTOCOL_UDP);

if (s == SOCKET_ERROR)
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_INFO, "socket failed");

/* setup address structure */
memset((char *) &si_other, 0, sizeof(si_other));

in_target.port = port;
in_target.server = server;
in_target.domain = SOCKET_DOMAIN_INET;

socket_set_target(&si_other, &in_target);

NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_INFO, "Server IP Address: %s\n" , server);

}

void NETRETROPAD_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
{
static const struct retro_variable vars[] = {
Expand All @@ -584,6 +619,7 @@ void NETRETROPAD_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)
{ "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_hide_analog_mismatch", "Hide mismatching analog button inputs; True|False" },
{ NULL, NULL },
};
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
Expand All @@ -606,27 +642,35 @@ void NETRETROPAD_CORE_PREFIX(retro_set_environment)(retro_environment_t cb)

static void netretropad_check_variables(void)
{
struct retro_variable var, var2, var3, var4, port_var, screen_var;
struct retro_variable var, var2, var3, var4, port_var, screen_var, hide_a_var;
var.key = "net_retropad_ip_octet1";
var2.key = "net_retropad_ip_octet2";
var3.key = "net_retropad_ip_octet3";
var4.key = "net_retropad_ip_octet4";
port_var.key = "net_retropad_port";
screen_var.key = "net_retropad_screen";
hide_a_var.key = "net_retropad_hide_analog_mismatch";

NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &var2);
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &var3);
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &var4);
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &port_var);
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &screen_var);
NETRETROPAD_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_GET_VARIABLE, &hide_a_var);

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

if (screen_var.value &&
((current_screen == NETRETROPAD_SCREEN_PAD && strstr(screen_var.value,"Keyboard")) ||
(current_screen == NETRETROPAD_SCREEN_KEYBOARD && strstr(screen_var.value,"Retropad"))))
flip_screen();
if (hide_a_var.value && strstr(hide_a_var.value,"True"))
hide_analog_mismatch = true;
else
hide_analog_mismatch = false;

}

void NETRETROPAD_CORE_PREFIX(retro_set_audio_sample)(retro_audio_sample_t cb)
Expand Down Expand Up @@ -656,7 +700,10 @@ void NETRETROPAD_CORE_PREFIX(retro_set_video_refresh)(retro_video_refresh_t cb)
}

void NETRETROPAD_CORE_PREFIX(retro_reset)(void)
{}
{
netretropad_check_variables();
open_UDP_socket();
}

void NETRETROPAD_CORE_PREFIX(retro_run)(void)
{
Expand All @@ -676,31 +723,60 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
int offset = DESC_OFFSET(&joypad, 0, 0, i);
if (joypad.value[offset])
input_state |= 1 << i;

/* Construct a red gradient representation for analog buttons */
offset = DESC_OFFSET(&analog_button, 0, RETRO_DEVICE_INDEX_ANALOG_BUTTON, i);
analog_item_colors[i] = (uint16_t)((int16_t)analog_button.value[offset]/1638) << 11;
}

for (i = analog.id_min; i <= analog.id_max; i++)
{
/* bitmap: x-- x- x+ x++ y-- y- y+ y++*/
/* default analog deadzone: 0.0 - increased for convenience, default analog threshold: 0.5 */
/* 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] < -32766/2)
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;
}

offset = DESC_OFFSET(&analog, 0, RETRO_DEVICE_INDEX_ANALOG_RIGHT, i);
if ( (int16_t)analog.value[offset] < -32766/2)
if ( (int16_t)analog.value[offset] < -32768/2)
{
input_state |= 1 << (16 + i*8 + 4);
analog_item_colors[ 16 + i*8 + 4] = (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 + 5);
analog_item_colors[ 16 + i*8 + 5] = (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 + 7);
analog_item_colors[ 16 + i*8 + 7] = (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 + 6);
analog_item_colors[ 16 + i*8 + 6] = (uint16_t)(( ((int16_t)analog.value[offset]) ) /528) << 11;
}
}

/* Input test section start. */
Expand All @@ -713,7 +789,7 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
}

/* Print a log for A+B combination, but only once while those are pressed */
if (input_state == ((1 << RETRO_DEVICE_ID_JOYPAD_A | 1 << RETRO_DEVICE_ID_JOYPAD_B) & 0x0000ffff))
if (input_state & ((1 << RETRO_DEVICE_ID_JOYPAD_A | 1 << RETRO_DEVICE_ID_JOYPAD_B) & 0x0000ffff))
{
if (!dump_state_blocked)
{
Expand Down Expand Up @@ -801,39 +877,37 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)

for (runs = retropad_buttons[rle++]; runs > 0; runs--)
{
unsigned button = 0;
unsigned button_analog = 0;
int offset;
if (paint)
{
unsigned button = 0;
unsigned button_analog = 0;
unsigned count;
uint16_t color;

/* 0 - 15: buttons, 16 - 31: analog x/y */
/* 32 - 47: analog input for same buttons */
if (retropad_buttons[rle] < 32)
button = paint ? 1 << retropad_buttons[rle] : 0;
button = 1 << retropad_buttons[rle];
else
{
button_analog = paint ? 1 << (retropad_buttons[rle] - 32) : 0;
offset = DESC_OFFSET(&analog_button, 0, RETRO_DEVICE_INDEX_ANALOG_BUTTON, retropad_buttons[rle] - 32);
}
rle++;
}

if (paint)
{
unsigned count;
uint16_t color;
button_analog = 1 << (retropad_buttons[rle] - 32);

/* Red for active inputs */
if (input_state & button)
{
color = 0xA000;
if(retropad_buttons[rle]<16)
color = 0xA000;
else
/* Gradient for analog axes */
color = analog_item_colors[retropad_buttons[rle]];
input_state_validated |= button;
}
/* Red gradient for active analog button inputs, from 0 to 0xa000 */
else if (button_analog && (int16_t)analog_button.value[offset] > 3276)
else if (button_analog && analog_item_colors[retropad_buttons[rle] - 32])
{
color = (uint16_t)((int16_t)analog_button.value[offset]/1638) << 11;
color = analog_item_colors[retropad_buttons[rle] - 32];
}
else if (button_analog && hide_analog_mismatch && input_state & button_analog)
color = 0xA000;
else
{
/* Light blue for expected input */
Expand All @@ -847,6 +921,7 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
color = 0xffff;
}

rle++;
for (count = retropad_buttons[rle++]; count > 0; count--)
*pixel++ = color;
}
Expand All @@ -861,31 +936,27 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)
}
else if (current_screen == NETRETROPAD_SCREEN_KEYBOARD)
{
for (rle = 0; rle < (sizeof(keyboard_buttons)/sizeof(keyboard_buttons[0])); )
for (rle = 0; rle < ARRAY_SIZE(keyboard_buttons); )
{
unsigned runs;
char paint = 0;

for (runs = keyboard_buttons[rle++]; runs > 0; runs--)
{
unsigned button = 0;
unsigned button_analog = 0;
int offset;

if (paint)
{
unsigned count;
uint16_t color;

/* Red for active inputs */
/* Same color scheme as for retropad buttons */
if (keyboard_state[keyboard_buttons[rle]])
{
color = 0xA000;
keyboard_state_validated[keyboard_buttons[rle]] = true;
}
else
{
if (expected_input == keyboard_buttons[rle])
if (expected_input > 0 && expected_input == keyboard_buttons[rle])
color = 0x7fff;
else if (keyboard_state_validated[keyboard_buttons[rle]])
color = 0xbff7;
Expand Down Expand Up @@ -913,29 +984,8 @@ void NETRETROPAD_CORE_PREFIX(retro_run)(void)

bool NETRETROPAD_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info)
{
socket_target_t in_target;

netretropad_check_variables();

s = socket_create(
"retropad",
SOCKET_DOMAIN_INET,
SOCKET_TYPE_DATAGRAM,
SOCKET_PROTOCOL_UDP);

if (s == SOCKET_ERROR)
NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_INFO, "socket failed");

/* setup address structure */
memset((char *) &si_other, 0, sizeof(si_other));

in_target.port = port;
in_target.server = server;
in_target.domain = SOCKET_DOMAIN_INET;

socket_set_target(&si_other, &in_target);

NETRETROPAD_CORE_PREFIX(log_cb)(RETRO_LOG_INFO, "Server IP Address: %s\n" , server);
open_UDP_socket();

/* If a .ratst file is given (only possible via command line),
* initialize test sequence. */
Expand Down
12 changes: 8 additions & 4 deletions input/input_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,12 +1336,16 @@ static void input_remote_parse_packet(
switch (msg->device)
{
case RETRO_DEVICE_JOYPAD:
input_state->buttons[user] &= ~(1 << msg->id);
if (msg->state)
input_state->buttons[user] |= 1 << msg->id;
if (msg->id < 16)
{
input_state->buttons[user] &= ~(1 << msg->id);
if (msg->state)
input_state->buttons[user] |= 1 << msg->id;
}
break;
case RETRO_DEVICE_ANALOG:
input_state->analog[msg->index * 2 + msg->id][user] = msg->state;
if (msg->id<2 && msg->index<2)
input_state->analog[msg->index * 2 + msg->id][user] = msg->state;
break;
}
}
Expand Down

0 comments on commit aee7797

Please sign in to comment.