Skip to content

Commit 6301322

Browse files
committed
input_driver optimizations:
1) input_joypad_axis — Removed the redundant (1.0f / 0x7fff) * val * sensitivity round-trip through normalized 2) input_joypad_analog_button — Hoisted joypad_info->joy_idx into a local joy_idx 3) input_state_wrap axis comparison — Replaced two /0x8000 float divisions (one per joypad) with a single precomputed inv_0x8000 = 1.0f / 0x8000 multiplied in. 4) Analog-to-digital mapping loop — The inner (float)ret_axis / 0x7fff was computed up to 4 times per axis value (once per direction comparison). Now it's computed once as norm 5) input_state_internal - expression hoisted Hoisted into a single kb_blocked bool in an enclosing scope block. 6) input_keys_pressed — Same flag check was evaluated 3–4 times across the function body plus once per iteration of the meta-key for loop. Hoisted into a single kb_blocked local 7) input_keyboard_event accessibility path — Eliminated a malloc(2) + free() call per keypress for a 2-byte string
1 parent 3a0eab5 commit 6301322

1 file changed

Lines changed: 75 additions & 62 deletions

File tree

input/input_driver.c

Lines changed: 75 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ static int32_t input_state_wrap(
809809
const uint64_t autobind_joyaxis= joypad_info->auto_binds[id].joyaxis;
810810
uint16_t port = joypad_info->joy_idx;
811811
float axis_threshold = joypad_info->axis_threshold;
812+
float inv_0x8000 = 1.0f / 0x8000;
812813
const uint64_t joykey = (bind_joykey != NO_BTN)
813814
? bind_joykey : autobind_joykey;
814815
const uint64_t joyaxis = (bind_joyaxis != AXIS_NONE)
@@ -821,7 +822,7 @@ static int32_t input_state_wrap(
821822
return 1;
822823
if (joyaxis != AXIS_NONE &&
823824
((float)abs(joypad->axis(port, (uint32_t)joyaxis))
824-
/ 0x8000) > axis_threshold)
825+
* inv_0x8000) > axis_threshold)
825826
return 1;
826827
}
827828
if (sec_joypad)
@@ -831,7 +832,7 @@ static int32_t input_state_wrap(
831832
return 1;
832833
if (joyaxis != AXIS_NONE &&
833834
((float)abs(sec_joypad->axis(port, (uint32_t)joyaxis))
834-
/ 0x8000) > axis_threshold)
835+
* inv_0x8000) > axis_threshold)
835836
return 1;
836837
}
837838
}
@@ -866,35 +867,36 @@ static int16_t input_joypad_axis(
866867
const input_device_driver_t *drv,
867868
unsigned port, uint32_t joyaxis, float normal_mag)
868869
{
869-
int16_t val = ((joyaxis != AXIS_NONE) && drv && drv->axis)
870-
? drv->axis(port, joyaxis) : 0;
870+
int16_t val = ((joyaxis != AXIS_NONE) && drv && drv->axis)
871+
? drv->axis(port, joyaxis) : 0;
871872

872873
if (input_analog_deadzone)
873874
{
874-
/* if analog value is below the deadzone, ignore it
875-
* normal magnitude is calculated radially for analog sticks
876-
* and linearly for analog buttons */
875+
/* If below deadzone, short-circuit immediately */
877876
if (normal_mag <= input_analog_deadzone)
878877
return 0;
879878

880-
/* Due to the way normal_mag is calculated differently
881-
* for buttons and sticks, this results in either a
882-
* radial scaled deadzone for sticks or linear scaled
883-
* deadzone for analog buttons */
884-
val = val * MAX(1.0f,(1.0f / normal_mag)) * MIN(1.0f,
885-
((normal_mag - input_analog_deadzone)
886-
/ (1.0f - input_analog_deadzone)));
879+
/* Radial/linear scaled deadzone rescale.
880+
* Precompute 1/normal_mag once; clamp implicitly via MIN/MAX. */
881+
{
882+
float inv_mag = (normal_mag > 1.0f) ? (1.0f / normal_mag) : 1.0f;
883+
float dz_scale = (normal_mag - input_analog_deadzone)
884+
/ (1.0f - input_analog_deadzone);
885+
if (dz_scale > 1.0f) dz_scale = 1.0f;
886+
val = (int16_t)((float)val * inv_mag * dz_scale);
887+
}
887888
}
888889

889890
if (input_analog_sensitivity != 1.0f)
890891
{
891-
float normalized = (1.0f / 0x7fff) * val;
892-
int new_val = 0x7fff * normalized * input_analog_sensitivity;
892+
/* Fused: scale = sensitivity / 0x7fff; new_val = val * scale * 0x7fff
893+
* reduces to val * sensitivity, with clamp */
894+
int new_val = (int)((float)val * input_analog_sensitivity);
893895
if (new_val > 0x7fff)
894896
return 0x7fff;
895-
else if (new_val < -0x7fff)
897+
if (new_val < -0x7fff)
896898
return -0x7fff;
897-
return new_val;
899+
return (int16_t)new_val;
898900
}
899901

900902
return val;
@@ -929,30 +931,32 @@ static int16_t input_joypad_analog_button(
929931
{
930932
int16_t res = 0;
931933
float normal_mag = 0.0f;
934+
uint16_t joy_idx = joypad_info->joy_idx;
932935
uint32_t axis = (bind->joyaxis == AXIS_NONE)
933936
? joypad_info->auto_binds[ident].joyaxis
934937
: bind->joyaxis;
935938

936-
/* Analog button. */
937-
if (input_analog_deadzone)
939+
/* Analog button - call drv->axis at most once */
940+
if (input_analog_deadzone && axis != AXIS_NONE)
938941
{
939-
int16_t mult = 0;
940-
if (axis != AXIS_NONE)
941-
if ((mult = drv->axis(joypad_info->joy_idx, axis)) != 0)
942-
normal_mag = fabs((1.0f / 0x7fff) * mult);
942+
int16_t mult = drv->axis(joy_idx, axis);
943+
if (mult != 0)
944+
{
945+
/* Manual abs avoids fabs() float-to-int rounding ambiguity */
946+
normal_mag = (float)(mult < 0 ? -mult : mult) * (1.0f / 0x7fff);
947+
}
943948
}
944949

945-
/* If the result is zero, it's got a digital button
946-
* attached to it instead */
950+
/* If the result is zero, it's got a digital button attached to it instead */
947951
if ((res = abs(input_joypad_axis(input_analog_deadzone,
948952
input_analog_sensitivity, drv,
949-
joypad_info->joy_idx, axis, normal_mag))) == 0)
953+
joy_idx, axis, normal_mag))) == 0)
950954
{
951955
uint16_t key = (bind->joykey == NO_BTN)
952956
? joypad_info->auto_binds[ident].joykey
953957
: bind->joykey;
954958

955-
if (drv->button(joypad_info->joy_idx, key))
959+
if (drv->button(joy_idx, key))
956960
return 0x7fff;
957961
return 0;
958962
}
@@ -1906,6 +1910,10 @@ static int16_t input_state_internal(
19061910
&& (id == RETRO_DEVICE_ID_JOYPAD_MASK);
19071911
joypad_info.axis_threshold = settings->floats.input_axis_threshold;
19081912

1913+
/* Cache once; flag does not change during this function */
1914+
{
1915+
bool kb_mapping_blocked = (input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false;
1916+
19091917
/* Loop over all 'physical' ports mapped to specified
19101918
* 'virtual' port index */
19111919
while ((mapped_port = *(input_remap_port_map++)) < MAX_USERS)
@@ -1959,7 +1967,7 @@ static int16_t input_state_internal(
19591967
sec_joypad,
19601968
&joypad_info,
19611969
(*input_st->libretro_input_binds),
1962-
(input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false,
1970+
kb_mapping_blocked,
19631971
mapped_port, device, idx, id);
19641972

19651973
/* Ignore analog sticks when using Analog to Digital */
@@ -2060,6 +2068,8 @@ static int16_t input_state_internal(
20602068
int16_t ret_axis;
20612069
uint8_t s;
20622070
uint8_t a;
2071+
float axis_thr = joypad_info.axis_threshold;
2072+
float inv_0x7fff = 1.0f / 0x7fff;
20632073

20642074
for (s = RETRO_DEVICE_INDEX_ANALOG_LEFT; s <= RETRO_DEVICE_INDEX_ANALOG_RIGHT; s++)
20652075
{
@@ -2081,31 +2091,32 @@ static int16_t input_state_internal(
20812091

20822092
if (ret_axis)
20832093
{
2084-
int bit = -1;
2094+
float norm = (float)ret_axis * inv_0x7fff;
2095+
int bit = -1;
20852096

2086-
if (a == RETRO_DEVICE_ID_ANALOG_Y && (float)ret_axis / 0x7fff < -joypad_info.axis_threshold)
2097+
if (a == RETRO_DEVICE_ID_ANALOG_Y && norm < -axis_thr)
20872098
{
20882099
if (input_analog_dpad_mode == ANALOG_DPAD_TWINSTICK && s == RETRO_DEVICE_INDEX_ANALOG_RIGHT)
20892100
bit = RETRO_DEVICE_ID_JOYPAD_X;
20902101
else
20912102
bit = RETRO_DEVICE_ID_JOYPAD_UP;
20922103
}
2093-
else if (a == RETRO_DEVICE_ID_ANALOG_Y && (float)ret_axis / 0x7fff > joypad_info.axis_threshold)
2104+
else if (a == RETRO_DEVICE_ID_ANALOG_Y && norm > axis_thr)
20942105
{
20952106
if (input_analog_dpad_mode == ANALOG_DPAD_TWINSTICK && s == RETRO_DEVICE_INDEX_ANALOG_RIGHT)
20962107
bit = RETRO_DEVICE_ID_JOYPAD_B;
20972108
else
20982109
bit = RETRO_DEVICE_ID_JOYPAD_DOWN;
20992110
}
21002111

2101-
if (a == RETRO_DEVICE_ID_ANALOG_X && (float)ret_axis / 0x7fff < -joypad_info.axis_threshold)
2112+
if (a == RETRO_DEVICE_ID_ANALOG_X && norm < -axis_thr)
21022113
{
21032114
if (input_analog_dpad_mode == ANALOG_DPAD_TWINSTICK && s == RETRO_DEVICE_INDEX_ANALOG_RIGHT)
21042115
bit = RETRO_DEVICE_ID_JOYPAD_Y;
21052116
else
21062117
bit = RETRO_DEVICE_ID_JOYPAD_LEFT;
21072118
}
2108-
else if (a == RETRO_DEVICE_ID_ANALOG_X && (float)ret_axis / 0x7fff > joypad_info.axis_threshold)
2119+
else if (a == RETRO_DEVICE_ID_ANALOG_X && norm > axis_thr)
21092120
{
21102121
if (input_analog_dpad_mode == ANALOG_DPAD_TWINSTICK && s == RETRO_DEVICE_INDEX_ANALOG_RIGHT)
21112122
bit = RETRO_DEVICE_ID_JOYPAD_A;
@@ -2154,6 +2165,7 @@ static int16_t input_state_internal(
21542165
else
21552166
result |= port_result;
21562167
}
2168+
} /* kb_mapping_blocked scope */
21572169

21582170
return result;
21592171
}
@@ -6127,6 +6139,10 @@ static void input_keys_pressed(
61276139
&& (libretro_hotkey_set || keyboard_hotkey_set))
61286140
libretro_hotkey_set = keyboard_hotkey_set = true;
61296141

6142+
/* Cache once - flag does not change during a single poll */
6143+
{
6144+
bool kb_blocked = (input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false;
6145+
61306146
if ( (port == hotkey_port)
61316147
&& (binds_norm->valid || binds_auto->valid)
61326148
&& CHECK_INPUT_DRIVER_BLOCK_HOTKEY(binds_norm, binds_auto))
@@ -6138,7 +6154,7 @@ static void input_keys_pressed(
61386154
sec_joypad,
61396155
joypad_info,
61406156
binds,
6141-
(input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false,
6157+
kb_blocked,
61426158
port, RETRO_DEVICE_JOYPAD, 0,
61436159
RARCH_ENABLE_HOTKEY))
61446160
{
@@ -6170,7 +6186,7 @@ static void input_keys_pressed(
61706186
sec_joypad,
61716187
joypad_info,
61726188
binds,
6173-
(input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false,
6189+
kb_blocked,
61746190
port, RETRO_DEVICE_JOYPAD, 0,
61756191
RETRO_DEVICE_ID_JOYPAD_MASK);
61766192

@@ -6413,7 +6429,7 @@ static void input_keys_pressed(
64136429
sec_joypad,
64146430
joypad_info,
64156431
binds,
6416-
(input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false,
6432+
kb_blocked,
64176433
port, RETRO_DEVICE_JOYPAD, 0,
64186434
i);
64196435

@@ -6482,6 +6498,8 @@ static void input_keys_pressed(
64826498

64836499
if (input_st->flags & INP_FLAG_BLOCK_HOTKEY && !enable_hotkey_pressed)
64846500
input_st->input_hotkey_block_counter = 0;
6501+
6502+
} /* kb_blocked scope */
64856503
}
64866504

64876505
void input_driver_poll(void)
@@ -7747,32 +7765,27 @@ void input_keyboard_event(bool down, unsigned code,
77477765
{
77487766
if (code != 303 && code != 0)
77497767
{
7750-
char* say_char = (char*)malloc(sizeof(char)+1);
7751-
7752-
if (say_char)
7768+
char say_char[2];
7769+
char c = (char)character;
7770+
say_char[0] = c;
7771+
say_char[1] = '\0';
7772+
7773+
if (character == 127 || character == 8)
7774+
accessibility_speak_priority(accessibility_enable,
7775+
accessibility_narrator_speech_speed, "backspace", 10);
7776+
else
77537777
{
7754-
char c = (char)character;
7755-
*say_char = c;
7756-
say_char[1] = '\0';
7757-
7758-
if (character == 127 || character == 8)
7759-
accessibility_speak_priority(accessibility_enable,
7760-
accessibility_narrator_speech_speed, "backspace", 10);
7761-
else
7762-
{
7763-
const char *lut_name = accessibility_lut_name(c);
7764-
if (lut_name)
7765-
accessibility_speak_priority(
7766-
accessibility_enable,
7767-
accessibility_narrator_speech_speed,
7768-
lut_name, 10);
7769-
else if (character != 0)
7770-
accessibility_speak_priority(
7771-
accessibility_enable,
7772-
accessibility_narrator_speech_speed,
7773-
say_char, 10);
7774-
}
7775-
free(say_char);
7778+
const char *lut_name = accessibility_lut_name(c);
7779+
if (lut_name)
7780+
accessibility_speak_priority(
7781+
accessibility_enable,
7782+
accessibility_narrator_speech_speed,
7783+
lut_name, 10);
7784+
else if (character != 0)
7785+
accessibility_speak_priority(
7786+
accessibility_enable,
7787+
accessibility_narrator_speech_speed,
7788+
say_char, 10);
77767789
}
77777790
}
77787791
}

0 commit comments

Comments
 (0)