Skip to content

Commit 1d69a23

Browse files
NeroBurnerm42ukosfan5
authoredAug 27, 2021
Joystick sensitivity for player movement (#11262)
This commit deprecates the forward, backward, left, and right binary inputs currently used for player movement in the PlayerControl struct. In their place, it adds the movement_speed and movement_direction values, which represents the player movement is a polar coordinate system. movement_speed is a scalar from 0.0 to 1.0. movement_direction is an angle from 0 to +-Pi: FWD 0 _ LFT / \ RGT -Pi/2 | | +Pi/2 \_/ +-Pi BCK Boolean movement bits will still be set for server telegrams and Lua script invocations to provide full backward compatibility. When generating these values from an analog input, a direction is considered active when it is 22.5 degrees away from either orthogonal axis. Co-authored-by: Markus Koch <markus@notsyncing.net> Co-authored-by: sfan5 <sfan5@live.de>
1 parent 149d8fc commit 1d69a23

10 files changed

+138
-99
lines changed
 

‎src/client/content_cao.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -998,9 +998,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
998998
const PlayerControl &controls = player->getPlayerControl();
999999

10001000
bool walking = false;
1001-
if (controls.up || controls.down || controls.left || controls.right ||
1002-
controls.forw_move_joystick_axis != 0.f ||
1003-
controls.sidew_move_joystick_axis != 0.f)
1001+
if (controls.movement_speed > 0.001f)
10041002
walking = true;
10051003

10061004
f32 new_speed = player->local_animation_speed;
@@ -1015,9 +1013,10 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
10151013
g_settings->getBool("free_move") &&
10161014
m_client->checkLocalPrivilege("fly"))))
10171015
new_speed *= 1.5;
1018-
// slowdown speed if sneeking
1016+
// slowdown speed if sneaking
10191017
if (controls.sneak && walking)
10201018
new_speed /= 2;
1019+
new_speed *= controls.movement_speed;
10211020

10221021
if (walking && (controls.dig || controls.place)) {
10231022
new_anim = player->local_animations[3];

‎src/client/game.cpp

+40-37
Original file line numberDiff line numberDiff line change
@@ -2460,7 +2460,7 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
24602460

24612461
if (m_cache_enable_joysticks) {
24622462
f32 sens_scale = getSensitivityScaleFactor();
2463-
f32 c = m_cache_joystick_frustum_sensitivity * (1.f / 32767.f) * dtime * sens_scale;
2463+
f32 c = m_cache_joystick_frustum_sensitivity * dtime * sens_scale;
24642464
cam->camera_yaw -= input->joystick.getAxisWithoutDead(JA_FRUSTUM_HORIZONTAL) * c;
24652465
cam->camera_pitch += input->joystick.getAxisWithoutDead(JA_FRUSTUM_VERTICAL) * c;
24662466
}
@@ -2471,41 +2471,29 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
24712471

24722472
void Game::updatePlayerControl(const CameraOrientation &cam)
24732473
{
2474-
//TimeTaker tt("update player control", NULL, PRECISION_NANO);
2474+
LocalPlayer *player = client->getEnv().getLocalPlayer();
24752475

2476-
// DO NOT use the isKeyDown method for the forward, backward, left, right
2477-
// buttons, as the code that uses the controls needs to be able to
2478-
// distinguish between the two in order to know when to use joysticks.
2476+
//TimeTaker tt("update player control", NULL, PRECISION_NANO);
24792477

24802478
PlayerControl control(
2481-
input->isKeyDown(KeyType::FORWARD),
2482-
input->isKeyDown(KeyType::BACKWARD),
2483-
input->isKeyDown(KeyType::LEFT),
2484-
input->isKeyDown(KeyType::RIGHT),
2485-
isKeyDown(KeyType::JUMP),
2479+
isKeyDown(KeyType::JUMP) || player->getAutojump(),
24862480
isKeyDown(KeyType::AUX1),
24872481
isKeyDown(KeyType::SNEAK),
24882482
isKeyDown(KeyType::ZOOM),
24892483
isKeyDown(KeyType::DIG),
24902484
isKeyDown(KeyType::PLACE),
24912485
cam.camera_pitch,
24922486
cam.camera_yaw,
2493-
input->joystick.getAxisWithoutDead(JA_SIDEWARD_MOVE),
2494-
input->joystick.getAxisWithoutDead(JA_FORWARD_MOVE)
2487+
input->getMovementSpeed(),
2488+
input->getMovementDirection()
24952489
);
24962490

2497-
u32 keypress_bits = (
2498-
( (u32)(isKeyDown(KeyType::FORWARD) & 0x1) << 0) |
2499-
( (u32)(isKeyDown(KeyType::BACKWARD) & 0x1) << 1) |
2500-
( (u32)(isKeyDown(KeyType::LEFT) & 0x1) << 2) |
2501-
( (u32)(isKeyDown(KeyType::RIGHT) & 0x1) << 3) |
2502-
( (u32)(isKeyDown(KeyType::JUMP) & 0x1) << 4) |
2503-
( (u32)(isKeyDown(KeyType::AUX1) & 0x1) << 5) |
2504-
( (u32)(isKeyDown(KeyType::SNEAK) & 0x1) << 6) |
2505-
( (u32)(isKeyDown(KeyType::DIG) & 0x1) << 7) |
2506-
( (u32)(isKeyDown(KeyType::PLACE) & 0x1) << 8) |
2507-
( (u32)(isKeyDown(KeyType::ZOOM) & 0x1) << 9)
2508-
);
2491+
// autoforward if set: move towards pointed position at maximum speed
2492+
if (player->getPlayerSettings().continuous_forward &&
2493+
client->activeObjectsReceived() && !player->isDead()) {
2494+
control.movement_speed = 1.0f;
2495+
control.movement_direction = 0.0f;
2496+
}
25092497

25102498
#ifdef ANDROID
25112499
/* For Android, simulate holding down AUX1 (fast move) if the user has
@@ -2515,23 +2503,38 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
25152503
*/
25162504
if (m_cache_hold_aux1) {
25172505
control.aux1 = control.aux1 ^ true;
2518-
keypress_bits ^= ((u32)(1U << 5));
25192506
}
25202507
#endif
25212508

2522-
LocalPlayer *player = client->getEnv().getLocalPlayer();
2523-
2524-
// autojump if set: simulate "jump" key
2525-
if (player->getAutojump()) {
2526-
control.jump = true;
2527-
keypress_bits |= 1U << 4;
2528-
}
2509+
u32 keypress_bits = (
2510+
( (u32)(control.jump & 0x1) << 4) |
2511+
( (u32)(control.aux1 & 0x1) << 5) |
2512+
( (u32)(control.sneak & 0x1) << 6) |
2513+
( (u32)(control.dig & 0x1) << 7) |
2514+
( (u32)(control.place & 0x1) << 8) |
2515+
( (u32)(control.zoom & 0x1) << 9)
2516+
);
25292517

2530-
// autoforward if set: simulate "up" key
2531-
if (player->getPlayerSettings().continuous_forward &&
2532-
client->activeObjectsReceived() && !player->isDead()) {
2533-
control.up = true;
2534-
keypress_bits |= 1U << 0;
2518+
// Set direction keys to ensure mod compatibility
2519+
if (control.movement_speed > 0.001f) {
2520+
float absolute_direction;
2521+
2522+
// Check in original orientation (absolute value indicates forward / backward)
2523+
absolute_direction = abs(control.movement_direction);
2524+
if (absolute_direction < (3.0f / 8.0f * M_PI))
2525+
keypress_bits |= (u32)(0x1 << 0); // Forward
2526+
if (absolute_direction > (5.0f / 8.0f * M_PI))
2527+
keypress_bits |= (u32)(0x1 << 1); // Backward
2528+
2529+
// Rotate entire coordinate system by 90 degrees (absolute value indicates left / right)
2530+
absolute_direction = control.movement_direction + M_PI_2;
2531+
if (absolute_direction >= M_PI)
2532+
absolute_direction -= 2 * M_PI;
2533+
absolute_direction = abs(absolute_direction);
2534+
if (absolute_direction < (3.0f / 8.0f * M_PI))
2535+
keypress_bits |= (u32)(0x1 << 2); // Left
2536+
if (absolute_direction > (5.0f / 8.0f * M_PI))
2537+
keypress_bits |= (u32)(0x1 << 3); // Right
25352538
}
25362539

25372540
client->setPlayerControl(control);

‎src/client/inputhandler.h

+43
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ class InputHandler
240240
virtual bool wasKeyReleased(GameKeyType k) = 0;
241241
virtual bool cancelPressed() = 0;
242242

243+
virtual float getMovementSpeed() = 0;
244+
virtual float getMovementDirection() = 0;
245+
243246
virtual void clearWasKeyPressed() {}
244247
virtual void clearWasKeyReleased() {}
245248

@@ -285,6 +288,44 @@ class RealInputHandler : public InputHandler
285288
{
286289
return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k);
287290
}
291+
virtual float getMovementSpeed()
292+
{
293+
bool f = m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD]),
294+
b = m_receiver->IsKeyDown(keycache.key[KeyType::BACKWARD]),
295+
l = m_receiver->IsKeyDown(keycache.key[KeyType::LEFT]),
296+
r = m_receiver->IsKeyDown(keycache.key[KeyType::RIGHT]);
297+
if (f || b || l || r)
298+
{
299+
// if contradictory keys pressed, stay still
300+
if (f && b && l && r)
301+
return 0.0f;
302+
else if (f && b && !l && !r)
303+
return 0.0f;
304+
else if (!f && !b && l && r)
305+
return 0.0f;
306+
return 1.0f; // If there is a keyboard event, assume maximum speed
307+
}
308+
return joystick.getMovementSpeed();
309+
}
310+
virtual float getMovementDirection()
311+
{
312+
float x = 0, z = 0;
313+
314+
/* Check keyboard for input */
315+
if (m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD]))
316+
z += 1;
317+
if (m_receiver->IsKeyDown(keycache.key[KeyType::BACKWARD]))
318+
z -= 1;
319+
if (m_receiver->IsKeyDown(keycache.key[KeyType::RIGHT]))
320+
x += 1;
321+
if (m_receiver->IsKeyDown(keycache.key[KeyType::LEFT]))
322+
x -= 1;
323+
324+
if (x != 0 || z != 0) /* If there is a keyboard event, it takes priority */
325+
return atan2(x, z);
326+
else
327+
return joystick.getMovementDirection();
328+
}
288329
virtual bool cancelPressed()
289330
{
290331
return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey);
@@ -352,6 +393,8 @@ class RandomInputHandler : public InputHandler
352393
virtual bool wasKeyPressed(GameKeyType k) { return false; }
353394
virtual bool wasKeyReleased(GameKeyType k) { return false; }
354395
virtual bool cancelPressed() { return false; }
396+
virtual float getMovementSpeed() {return 0.0f;}
397+
virtual float getMovementDirection() {return 0.0f;}
355398
virtual v2s32 getMousePos() { return mousepos; }
356399
virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); }
357400

‎src/client/joystick_controller.cpp

+21-3
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ JoystickController::JoystickController() :
160160
for (float &i : m_past_pressed_time) {
161161
i = 0;
162162
}
163+
m_layout.axes_deadzone = 0;
163164
clear();
164165
}
165166

@@ -251,10 +252,27 @@ void JoystickController::clear()
251252
memset(m_axes_vals, 0, sizeof(m_axes_vals));
252253
}
253254

254-
s16 JoystickController::getAxisWithoutDead(JoystickAxis axis)
255+
float JoystickController::getAxisWithoutDead(JoystickAxis axis)
255256
{
256257
s16 v = m_axes_vals[axis];
258+
257259
if (abs(v) < m_layout.axes_deadzone)
258-
return 0;
259-
return v;
260+
return 0.0f;
261+
262+
v += (v < 0 ? m_layout.axes_deadzone : -m_layout.axes_deadzone);
263+
264+
return (float)v / ((float)(INT16_MAX - m_layout.axes_deadzone));
265+
}
266+
267+
float JoystickController::getMovementDirection()
268+
{
269+
return atan2(getAxisWithoutDead(JA_SIDEWARD_MOVE), -getAxisWithoutDead(JA_FORWARD_MOVE));
270+
}
271+
272+
float JoystickController::getMovementSpeed()
273+
{
274+
float speed = sqrt(pow(getAxisWithoutDead(JA_FORWARD_MOVE), 2) + pow(getAxisWithoutDead(JA_SIDEWARD_MOVE), 2));
275+
if (speed > 1.0f)
276+
speed = 1.0f;
277+
return speed;
260278
}

‎src/client/joystick_controller.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,10 @@ class JoystickController {
144144
return m_axes_vals[axis];
145145
}
146146

147-
s16 getAxisWithoutDead(JoystickAxis axis);
147+
float getAxisWithoutDead(JoystickAxis axis);
148+
149+
float getMovementDirection();
150+
float getMovementSpeed();
148151

149152
f32 doubling_dtime;
150153

‎src/client/localplayer.cpp

+4-20
Original file line numberDiff line numberDiff line change
@@ -566,23 +566,7 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
566566
}
567567
}
568568

569-
if (control.up)
570-
speedH += v3f(0.0f, 0.0f, 1.0f);
571-
572-
if (control.down)
573-
speedH -= v3f(0.0f, 0.0f, 1.0f);
574-
575-
if (!control.up && !control.down)
576-
speedH -= v3f(0.0f, 0.0f, 1.0f) * (control.forw_move_joystick_axis / 32767.f);
577-
578-
if (control.left)
579-
speedH += v3f(-1.0f, 0.0f, 0.0f);
580-
581-
if (control.right)
582-
speedH += v3f(1.0f, 0.0f, 0.0f);
583-
584-
if (!control.left && !control.right)
585-
speedH += v3f(1.0f, 0.0f, 0.0f) * (control.sidew_move_joystick_axis / 32767.f);
569+
speedH = v3f(sin(control.movement_direction), 0.0f, cos(control.movement_direction));
586570

587571
if (m_autojump) {
588572
// release autojump after a given time
@@ -639,6 +623,8 @@ void LocalPlayer::applyControl(float dtime, Environment *env)
639623
else
640624
speedH = speedH.normalize() * movement_speed_walk;
641625

626+
speedH *= control.movement_speed; /* Apply analog input */
627+
642628
// Acceleration increase
643629
f32 incH = 0.0f; // Horizontal (X, Z)
644630
f32 incV = 0.0f; // Vertical (Y)
@@ -1106,9 +1092,7 @@ void LocalPlayer::handleAutojump(f32 dtime, Environment *env,
11061092
if (m_autojump)
11071093
return;
11081094

1109-
bool control_forward = control.up ||
1110-
(!control.up && !control.down &&
1111-
control.forw_move_joystick_axis < -0.05f);
1095+
bool control_forward = keyPressed & (1 << 0);
11121096

11131097
bool could_autojump =
11141098
m_can_jump && !control.jump && !control.sneak && control_forward;

‎src/network/serverpackethandler.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -510,10 +510,6 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
510510
playersao->setWantedRange(wanted_range);
511511

512512
player->keyPressed = keyPressed;
513-
player->control.up = (keyPressed & (0x1 << 0));
514-
player->control.down = (keyPressed & (0x1 << 1));
515-
player->control.left = (keyPressed & (0x1 << 2));
516-
player->control.right = (keyPressed & (0x1 << 3));
517513
player->control.jump = (keyPressed & (0x1 << 4));
518514
player->control.aux1 = (keyPressed & (0x1 << 5));
519515
player->control.sneak = (keyPressed & (0x1 << 6));

‎src/player.h

+7-18
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ struct PlayerControl
4949
PlayerControl() = default;
5050

5151
PlayerControl(
52-
bool a_up,
53-
bool a_down,
54-
bool a_left,
55-
bool a_right,
5652
bool a_jump,
5753
bool a_aux1,
5854
bool a_sneak,
@@ -61,14 +57,10 @@ struct PlayerControl
6157
bool a_place,
6258
float a_pitch,
6359
float a_yaw,
64-
float a_sidew_move_joystick_axis,
65-
float a_forw_move_joystick_axis
60+
float a_movement_speed,
61+
float a_movement_direction
6662
)
6763
{
68-
up = a_up;
69-
down = a_down;
70-
left = a_left;
71-
right = a_right;
7264
jump = a_jump;
7365
aux1 = a_aux1;
7466
sneak = a_sneak;
@@ -77,13 +69,9 @@ struct PlayerControl
7769
place = a_place;
7870
pitch = a_pitch;
7971
yaw = a_yaw;
80-
sidew_move_joystick_axis = a_sidew_move_joystick_axis;
81-
forw_move_joystick_axis = a_forw_move_joystick_axis;
72+
movement_speed = a_movement_speed;
73+
movement_direction = a_movement_direction;
8274
}
83-
bool up = false;
84-
bool down = false;
85-
bool left = false;
86-
bool right = false;
8775
bool jump = false;
8876
bool aux1 = false;
8977
bool sneak = false;
@@ -92,8 +80,9 @@ struct PlayerControl
9280
bool place = false;
9381
float pitch = 0.0f;
9482
float yaw = 0.0f;
95-
float sidew_move_joystick_axis = 0.0f;
96-
float forw_move_joystick_axis = 0.0f;
83+
// Note: These two are NOT available on the server
84+
float movement_speed = 0.0f;
85+
float movement_direction = 0.0f;
9786
};
9887

9988
struct PlayerSettings

‎src/script/lua_api/l_localplayer.cpp

+12-8
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,20 @@ int LuaLocalPlayer::l_get_control(lua_State *L)
223223
};
224224

225225
lua_createtable(L, 0, 12);
226-
set("up", c.up);
227-
set("down", c.down);
228-
set("left", c.left);
229-
set("right", c.right);
230-
set("jump", c.jump);
231-
set("aux1", c.aux1);
226+
set("jump", c.jump);
227+
set("aux1", c.aux1);
232228
set("sneak", c.sneak);
233-
set("zoom", c.zoom);
234-
set("dig", c.dig);
229+
set("zoom", c.zoom);
230+
set("dig", c.dig);
235231
set("place", c.place);
232+
// Player movement in polar coordinates and non-binary speed
233+
set("movement_speed", c.movement_speed);
234+
set("movement_direction", c.movement_direction);
235+
// Provide direction keys to ensure compatibility
236+
set("up", player->keyPressed & (1 << 0)); // Up, down, left, and right were removed in favor of
237+
set("down", player->keyPressed & (1 << 1)); // analog direction indicators and are therefore not
238+
set("left", player->keyPressed & (1 << 2)); // available as booleans anymore. The corresponding values
239+
set("right", player->keyPressed & (1 << 3)); // can still be read from the keyPressed bits though.
236240

237241
return 1;
238242
}

0 commit comments

Comments
 (0)
Please sign in to comment.