Skip to content

Commit 5eb45e1

Browse files
authoredJan 9, 2022
Restore pass-through of direction keys (#11924)
This moves relevant code into the PlayerControl class and gets rid of separate keyPressed variable.
1 parent 76dbd0d commit 5eb45e1

11 files changed

+165
-98
lines changed
 

Diff for: ‎src/client/client.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *
931931
v3f sf = myplayer->getSpeed() * 100;
932932
s32 pitch = myplayer->getPitch() * 100;
933933
s32 yaw = myplayer->getYaw() * 100;
934-
u32 keyPressed = myplayer->keyPressed;
934+
u32 keyPressed = myplayer->control.getKeysPressed();
935935
// scaled by 80, so that pi can fit into a u8
936936
u8 fov = clientMap->getCameraFov() * 80;
937937
u8 wanted_range = MYMIN(255,
@@ -1287,22 +1287,24 @@ void Client::sendPlayerPos()
12871287
if (!player)
12881288
return;
12891289

1290-
ClientMap &map = m_env.getClientMap();
1291-
u8 camera_fov = map.getCameraFov();
1292-
u8 wanted_range = map.getControl().wanted_range;
1293-
12941290
// Save bandwidth by only updating position when
12951291
// player is not dead and something changed
12961292

12971293
if (m_activeobjects_received && player->isDead())
12981294
return;
12991295

1296+
ClientMap &map = m_env.getClientMap();
1297+
u8 camera_fov = map.getCameraFov();
1298+
u8 wanted_range = map.getControl().wanted_range;
1299+
1300+
u32 keyPressed = player->control.getKeysPressed();
1301+
13001302
if (
13011303
player->last_position == player->getPosition() &&
13021304
player->last_speed == player->getSpeed() &&
13031305
player->last_pitch == player->getPitch() &&
13041306
player->last_yaw == player->getYaw() &&
1305-
player->last_keyPressed == player->keyPressed &&
1307+
player->last_keyPressed == keyPressed &&
13061308
player->last_camera_fov == camera_fov &&
13071309
player->last_wanted_range == wanted_range)
13081310
return;
@@ -1311,7 +1313,7 @@ void Client::sendPlayerPos()
13111313
player->last_speed = player->getSpeed();
13121314
player->last_pitch = player->getPitch();
13131315
player->last_yaw = player->getYaw();
1314-
player->last_keyPressed = player->keyPressed;
1316+
player->last_keyPressed = keyPressed;
13151317
player->last_camera_fov = camera_fov;
13161318
player->last_wanted_range = wanted_range;
13171319

Diff for: ‎src/client/clientlauncher.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ static void dump_start_data(const GameStartData &data)
7070

7171
ClientLauncher::~ClientLauncher()
7272
{
73-
delete receiver;
74-
7573
delete input;
7674

75+
delete receiver;
76+
7777
delete g_fontengine;
7878
delete g_gamecallback;
7979

Diff for: ‎src/client/game.cpp

+4-32
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,10 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
24812481
//TimeTaker tt("update player control", NULL, PRECISION_NANO);
24822482

24832483
PlayerControl control(
2484+
isKeyDown(KeyType::FORWARD),
2485+
isKeyDown(KeyType::BACKWARD),
2486+
isKeyDown(KeyType::LEFT),
2487+
isKeyDown(KeyType::RIGHT),
24842488
isKeyDown(KeyType::JUMP) || player->getAutojump(),
24852489
isKeyDown(KeyType::AUX1),
24862490
isKeyDown(KeyType::SNEAK),
@@ -2511,39 +2515,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
25112515
}
25122516
#endif
25132517

2514-
u32 keypress_bits = (
2515-
( (u32)(control.jump & 0x1) << 4) |
2516-
( (u32)(control.aux1 & 0x1) << 5) |
2517-
( (u32)(control.sneak & 0x1) << 6) |
2518-
( (u32)(control.dig & 0x1) << 7) |
2519-
( (u32)(control.place & 0x1) << 8) |
2520-
( (u32)(control.zoom & 0x1) << 9)
2521-
);
2522-
2523-
// Set direction keys to ensure mod compatibility
2524-
if (control.movement_speed > 0.001f) {
2525-
float absolute_direction;
2526-
2527-
// Check in original orientation (absolute value indicates forward / backward)
2528-
absolute_direction = abs(control.movement_direction);
2529-
if (absolute_direction < (3.0f / 8.0f * M_PI))
2530-
keypress_bits |= (u32)(0x1 << 0); // Forward
2531-
if (absolute_direction > (5.0f / 8.0f * M_PI))
2532-
keypress_bits |= (u32)(0x1 << 1); // Backward
2533-
2534-
// Rotate entire coordinate system by 90 degrees (absolute value indicates left / right)
2535-
absolute_direction = control.movement_direction + M_PI_2;
2536-
if (absolute_direction >= M_PI)
2537-
absolute_direction -= 2 * M_PI;
2538-
absolute_direction = abs(absolute_direction);
2539-
if (absolute_direction < (3.0f / 8.0f * M_PI))
2540-
keypress_bits |= (u32)(0x1 << 2); // Left
2541-
if (absolute_direction > (5.0f / 8.0f * M_PI))
2542-
keypress_bits |= (u32)(0x1 << 3); // Right
2543-
}
2544-
25452518
client->setPlayerControl(control);
2546-
player->keyPressed = keypress_bits;
25472519

25482520
//tt.stop();
25492521
}

Diff for: ‎src/client/inputhandler.h

+36-14
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,14 @@ class MyEventReceiver : public IEventReceiver
152152
// in the subsequent iteration of Game::processPlayerInteraction
153153
bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; }
154154

155-
void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); }
156-
void dontListenForKeys() { keysListenedFor.clear(); }
155+
void listenForKey(const KeyPress &keyCode)
156+
{
157+
keysListenedFor.set(keyCode);
158+
}
159+
void dontListenForKeys()
160+
{
161+
keysListenedFor.clear();
162+
}
157163

158164
s32 getMouseWheel()
159165
{
@@ -189,15 +195,15 @@ class MyEventReceiver : public IEventReceiver
189195
#endif
190196
}
191197

192-
s32 mouse_wheel = 0;
193-
194198
JoystickController *joystick = nullptr;
195199

196200
#ifdef HAVE_TOUCHSCREENGUI
197201
TouchScreenGUI *m_touchscreengui;
198202
#endif
199203

200204
private:
205+
s32 mouse_wheel = 0;
206+
201207
// The current state of keys
202208
KeyList keyIsDown;
203209

@@ -272,6 +278,12 @@ class RealInputHandler : public InputHandler
272278
{
273279
m_receiver->joystick = &joystick;
274280
}
281+
282+
virtual ~RealInputHandler()
283+
{
284+
m_receiver->joystick = nullptr;
285+
}
286+
275287
virtual bool isKeyDown(GameKeyType k)
276288
{
277289
return m_receiver->IsKeyDown(keycache.key[k]) || joystick.isKeyDown(k);
@@ -288,6 +300,7 @@ class RealInputHandler : public InputHandler
288300
{
289301
return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k);
290302
}
303+
291304
virtual float getMovementSpeed()
292305
{
293306
bool f = m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD]),
@@ -307,6 +320,7 @@ class RealInputHandler : public InputHandler
307320
}
308321
return joystick.getMovementSpeed();
309322
}
323+
310324
virtual float getMovementDirection()
311325
{
312326
float x = 0, z = 0;
@@ -326,10 +340,12 @@ class RealInputHandler : public InputHandler
326340
else
327341
return joystick.getMovementDirection();
328342
}
343+
329344
virtual bool cancelPressed()
330345
{
331346
return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey);
332347
}
348+
333349
virtual void clearWasKeyPressed()
334350
{
335351
m_receiver->clearWasKeyPressed();
@@ -338,34 +354,40 @@ class RealInputHandler : public InputHandler
338354
{
339355
m_receiver->clearWasKeyReleased();
340356
}
357+
341358
virtual void listenForKey(const KeyPress &keyCode)
342359
{
343360
m_receiver->listenForKey(keyCode);
344361
}
345-
virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); }
362+
virtual void dontListenForKeys()
363+
{
364+
m_receiver->dontListenForKeys();
365+
}
366+
346367
virtual v2s32 getMousePos()
347368
{
348-
if (RenderingEngine::get_raw_device()->getCursorControl()) {
349-
return RenderingEngine::get_raw_device()
350-
->getCursorControl()
351-
->getPosition();
369+
auto control = RenderingEngine::get_raw_device()->getCursorControl();
370+
if (control) {
371+
return control->getPosition();
352372
}
353373

354374
return m_mousepos;
355375
}
356376

357377
virtual void setMousePos(s32 x, s32 y)
358378
{
359-
if (RenderingEngine::get_raw_device()->getCursorControl()) {
360-
RenderingEngine::get_raw_device()
361-
->getCursorControl()
362-
->setPosition(x, y);
379+
auto control = RenderingEngine::get_raw_device()->getCursorControl();
380+
if (control) {
381+
control->setPosition(x, y);
363382
} else {
364383
m_mousepos = v2s32(x, y);
365384
}
366385
}
367386

368-
virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); }
387+
virtual s32 getMouseWheel()
388+
{
389+
return m_receiver->getMouseWheel();
390+
}
369391

370392
void clear()
371393
{

Diff for: ‎src/client/localplayer.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -1096,10 +1096,8 @@ void LocalPlayer::handleAutojump(f32 dtime, Environment *env,
10961096
if (m_autojump)
10971097
return;
10981098

1099-
bool control_forward = keyPressed & (1 << 0);
1100-
11011099
bool could_autojump =
1102-
m_can_jump && !control.jump && !control.sneak && control_forward;
1100+
m_can_jump && !control.jump && !control.sneak && control.isMoving();
11031101

11041102
if (!could_autojump)
11051103
return;

Diff for: ‎src/client/localplayer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class LocalPlayer : public Player
8686
v3f last_speed;
8787
float last_pitch = 0.0f;
8888
float last_yaw = 0.0f;
89-
unsigned int last_keyPressed = 0;
89+
u32 last_keyPressed = 0;
9090
u8 last_camera_fov = 0;
9191
u8 last_wanted_range = 0;
9292

Diff for: ‎src/network/serverpackethandler.cpp

+1-8
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,6 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
482482
f32 yaw = (f32)f32yaw / 100.0f;
483483
u32 keyPressed = 0;
484484

485-
// default behavior (in case an old client doesn't send these)
486485
f32 fov = 0;
487486
u8 wanted_range = 0;
488487

@@ -508,13 +507,7 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
508507
playersao->setFov(fov);
509508
playersao->setWantedRange(wanted_range);
510509

511-
player->keyPressed = keyPressed;
512-
player->control.jump = (keyPressed & (0x1 << 4));
513-
player->control.aux1 = (keyPressed & (0x1 << 5));
514-
player->control.sneak = (keyPressed & (0x1 << 6));
515-
player->control.dig = (keyPressed & (0x1 << 7));
516-
player->control.place = (keyPressed & (0x1 << 8));
517-
player->control.zoom = (keyPressed & (0x1 << 9));
510+
player->control.unpackKeysPressed(keyPressed);
518511

519512
if (playersao->checkMovementCheat()) {
520513
// Call callbacks

Diff for: ‎src/player.cpp

+59
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1919

2020
#include "player.h"
2121

22+
#include <cmath>
2223
#include "threading/mutex_auto_lock.h"
2324
#include "util/numeric.h"
2425
#include "hud.h"
@@ -159,6 +160,64 @@ void Player::clearHud()
159160
}
160161
}
161162

163+
#ifndef SERVER
164+
165+
u32 PlayerControl::getKeysPressed() const
166+
{
167+
u32 keypress_bits =
168+
( (u32)(jump & 1) << 4) |
169+
( (u32)(aux1 & 1) << 5) |
170+
( (u32)(sneak & 1) << 6) |
171+
( (u32)(dig & 1) << 7) |
172+
( (u32)(place & 1) << 8) |
173+
( (u32)(zoom & 1) << 9)
174+
;
175+
176+
// If any direction keys are pressed pass those through
177+
if (direction_keys != 0)
178+
{
179+
keypress_bits |= direction_keys;
180+
}
181+
// Otherwise set direction keys based on joystick movement (for mod compatibility)
182+
else if (isMoving())
183+
{
184+
float abs_d;
185+
186+
// (absolute value indicates forward / backward)
187+
abs_d = abs(movement_direction);
188+
if (abs_d < 3.0f / 8.0f * M_PI)
189+
keypress_bits |= (u32)1; // Forward
190+
if (abs_d > 5.0f / 8.0f * M_PI)
191+
keypress_bits |= (u32)1 << 1; // Backward
192+
193+
// rotate entire coordinate system by 90 degree
194+
abs_d = movement_direction + M_PI_2;
195+
if (abs_d >= M_PI)
196+
abs_d -= 2 * M_PI;
197+
abs_d = abs(abs_d);
198+
// (value now indicates left / right)
199+
if (abs_d < 3.0f / 8.0f * M_PI)
200+
keypress_bits |= (u32)1 << 2; // Left
201+
if (abs_d > 5.0f / 8.0f * M_PI)
202+
keypress_bits |= (u32)1 << 3; // Right
203+
}
204+
205+
return keypress_bits;
206+
}
207+
208+
#endif
209+
210+
void PlayerControl::unpackKeysPressed(u32 keypress_bits)
211+
{
212+
direction_keys = keypress_bits & 0xf;
213+
jump = keypress_bits & (1 << 4);
214+
aux1 = keypress_bits & (1 << 5);
215+
sneak = keypress_bits & (1 << 6);
216+
dig = keypress_bits & (1 << 7);
217+
place = keypress_bits & (1 << 8);
218+
zoom = keypress_bits & (1 << 9);
219+
}
220+
162221
void PlayerSettings::readGlobalSettings()
163222
{
164223
free_move = g_settings->getBool("free_move");

Diff for: ‎src/player.h

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

5151
PlayerControl(
52-
bool a_jump,
53-
bool a_aux1,
54-
bool a_sneak,
52+
bool a_up, bool a_down, bool a_left, bool a_right,
53+
bool a_jump, bool a_aux1, bool a_sneak,
5554
bool a_zoom,
56-
bool a_dig,
57-
bool a_place,
58-
float a_pitch,
59-
float a_yaw,
60-
float a_movement_speed,
61-
float a_movement_direction
55+
bool a_dig, bool a_place,
56+
float a_pitch, float a_yaw,
57+
float a_movement_speed, float a_movement_direction
6258
)
6359
{
60+
// Encode direction keys into a single value so nobody uses it accidentally
61+
// as movement_{speed,direction} is supposed to be the source of truth.
62+
direction_keys = (a_up&1) | ((a_down&1) << 1) |
63+
((a_left&1) << 2) | ((a_right&1) << 3);
6464
jump = a_jump;
6565
aux1 = a_aux1;
6666
sneak = a_sneak;
@@ -72,15 +72,26 @@ struct PlayerControl
7272
movement_speed = a_movement_speed;
7373
movement_direction = a_movement_direction;
7474
}
75+
76+
#ifndef SERVER
77+
// For client use
78+
u32 getKeysPressed() const;
79+
inline bool isMoving() const { return movement_speed > 0.001f; }
80+
#endif
81+
82+
// For server use
83+
void unpackKeysPressed(u32 keypress_bits);
84+
85+
u8 direction_keys = 0;
7586
bool jump = false;
7687
bool aux1 = false;
7788
bool sneak = false;
7889
bool zoom = false;
7990
bool dig = false;
8091
bool place = false;
92+
// Note: These four are NOT available on the server
8193
float pitch = 0.0f;
8294
float yaw = 0.0f;
83-
// Note: These two are NOT available on the server
8495
float movement_speed = 0.0f;
8596
float movement_direction = 0.0f;
8697
};
@@ -189,8 +200,6 @@ class Player
189200
return m_fov_override_spec;
190201
}
191202

192-
u32 keyPressed = 0;
193-
194203
HudElement* getHud(u32 id);
195204
u32 addHud(HudElement* hud);
196205
HudElement* removeHud(u32 id);

Diff for: ‎src/script/lua_api/l_localplayer.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,15 @@ int LuaLocalPlayer::l_get_control(lua_State *L)
230230
set("dig", c.dig);
231231
set("place", c.place);
232232
// Player movement in polar coordinates and non-binary speed
233-
set("movement_speed", c.movement_speed);
234-
set("movement_direction", c.movement_direction);
233+
lua_pushnumber(L, c.movement_speed);
234+
lua_setfield(L, -2, "movement_speed");
235+
lua_pushnumber(L, c.movement_direction);
236+
lua_setfield(L, -2, "movement_direction");
235237
// 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.
238+
set("up", c.direction_keys & (1 << 0));
239+
set("down", c.direction_keys & (1 << 1));
240+
set("left", c.direction_keys & (1 << 2));
241+
set("right", c.direction_keys & (1 << 3));
240242

241243
return 1;
242244
}

Diff for: ‎src/script/lua_api/l_object.cpp

+23-13
Original file line numberDiff line numberDiff line change
@@ -1367,20 +1367,18 @@ int ObjectRef::l_get_player_control(lua_State *L)
13671367
NO_MAP_LOCK_REQUIRED;
13681368
ObjectRef *ref = checkobject(L, 1);
13691369
RemotePlayer *player = getplayer(ref);
1370-
if (player == nullptr) {
1371-
lua_pushlstring(L, "", 0);
1372-
return 1;
1373-
}
1370+
if (player == nullptr)
1371+
return 0;
13741372

13751373
const PlayerControl &control = player->getPlayerControl();
13761374
lua_newtable(L);
1377-
lua_pushboolean(L, player->keyPressed & (1 << 0));
1375+
lua_pushboolean(L, control.direction_keys & (1 << 0));
13781376
lua_setfield(L, -2, "up");
1379-
lua_pushboolean(L, player->keyPressed & (1 << 1));
1377+
lua_pushboolean(L, control.direction_keys & (1 << 1));
13801378
lua_setfield(L, -2, "down");
1381-
lua_pushboolean(L, player->keyPressed & (1 << 2));
1379+
lua_pushboolean(L, control.direction_keys & (1 << 2));
13821380
lua_setfield(L, -2, "left");
1383-
lua_pushboolean(L, player->keyPressed & (1 << 3));
1381+
lua_pushboolean(L, control.direction_keys & (1 << 3));
13841382
lua_setfield(L, -2, "right");
13851383
lua_pushboolean(L, control.jump);
13861384
lua_setfield(L, -2, "jump");
@@ -1408,12 +1406,24 @@ int ObjectRef::l_get_player_control_bits(lua_State *L)
14081406
NO_MAP_LOCK_REQUIRED;
14091407
ObjectRef *ref = checkobject(L, 1);
14101408
RemotePlayer *player = getplayer(ref);
1411-
if (player == nullptr) {
1412-
lua_pushlstring(L, "", 0);
1413-
return 1;
1414-
}
1409+
if (player == nullptr)
1410+
return 0;
1411+
1412+
const auto &c = player->getPlayerControl();
1413+
1414+
// This is very close to PlayerControl::getKeysPressed() but duplicated
1415+
// here so the encoding in the API is not inadvertedly changed.
1416+
u32 keypress_bits =
1417+
c.direction_keys |
1418+
( (u32)(c.jump & 1) << 4) |
1419+
( (u32)(c.aux1 & 1) << 5) |
1420+
( (u32)(c.sneak & 1) << 6) |
1421+
( (u32)(c.dig & 1) << 7) |
1422+
( (u32)(c.place & 1) << 8) |
1423+
( (u32)(c.zoom & 1) << 9)
1424+
;
14151425

1416-
lua_pushnumber(L, player->keyPressed);
1426+
lua_pushinteger(L, keypress_bits);
14171427
return 1;
14181428
}
14191429

0 commit comments

Comments
 (0)
Please sign in to comment.