#105 Joystick control problem


In version 1.14, if the joystick direction is changed too quickly, Edgar won't change direction.

For example, if the player is holding the joystick to the left, and Edgar is moving left, and then the player quickly moves the joystick to the right, Edgar will continue to move left until the player centres the joystick. To get Edgar to change direction, the player must leave the joystick centred for a short time before pushing it in the new direction.

The length of time the player has to leave the joystick centred isn't very long - probably only a single game frame - but it's long enough for the player to notice the fact that you can't change direction too quickly.

I think a problem like this may have been reported a year or two ago, and then it was fixed - but it seems that since then, the fix has been undone, and the problem has come back again.


  • Palamedes

    Palamedes - 2014-02-01

    I think I've found what's causing the problem.

    In file: src/input.c line:540 and line:550, there's a condition:

    if (input.xAxisMoved == FALSE)

    If that condition is met, then the value of input.xAxisMoved is set to TRUE in line 544 or 554. However, the only place where the value of input.xAxisMoved is set to FALSE, is in line 562. And because line 562 is in the else clause of the condition in line 538 and 548, the only time it is ever executed is when the joystick X axis is within the dead zone.

    I'm not sure what the purpose of input.xAxisMoved is; am I right in thinking it's there to prevent axis movements causing problems in the menus?

    I can see that when the user is navigating a menu with a joystick, they would expect the menu entry selection to move just one step each time they push the joystick. If the user wanted to move the selection twice, they would push the joystick, then release it, and then push it again. If you don't check that the user has released the joystick before pushing it again, then each small joystick movement outside the deadzone will result in a separate menu selection movement. The upshot of that would be that if the user holds the stick in one direction for more than one game frame, but there is drift on the joystick, then a separate menu selection movement will be created for every game frame. This would make it very hard to move the menu selection by just one step at a time, instead of lots of steps. So I guess that the point of checking input.xAxisMoved is to prevent that problem, right?

    If so, then the fact that it's possible to use the analog axis to select items in the menu is a good thing. But checking the same condition in the game stops the player being able to change direction quickly.

    I think the solution to the problem is to change line 540 and line 550, so that the condition is met not only if input.xAxisMoved is FALSE, but also if it's in the game, and not one of the menus (including the inventory menu).

    Perhaps this could be done by amending lines 540 and 550 in src/input.c to the following:

    if (input.xAxisMoved == FALSE || game.status == IN_GAME)

    Haven't checked if this works yet - but if it does, then presumably a similar thing is also true for the Y axis.

  • Palamedes

    Palamedes - 2014-02-01

    Okay - I've tested the following changes:

    line 540: if (input.xAxisMoved == FALSE || game.status == IN_GAME)
    line 550: if (input.xAxisMoved == FALSE || game.status == IN_GAME)
    line 570: if (input.yAxisMoved == FALSE || game.status == IN_GAME)
    line 580: if (input.yAxisMoved == FALSE || game.status == IN_GAME)

    I made no other changes. I checked that you can use an analog joystick to move the selector one step at a time up and down in the main menu, and in any direction on the inventory screen - and you can. I checked that changing Edgar's direction left and right, and the slime's direction left, right, up and down during gameplay works, and it does; no matter how fast I waggle the joystick, it always responds. I also checked that my changes doesn't stop the player from being able to ride the lifts up and down - and it doesn't. No unexpected effects resulting from switching between gameplay and menus either.

    Can't think of anything else that this change is likely to break - so I hope to see a fix like this in version 1.15, thanks.

  • Palamedes

    Palamedes - 2014-02-01

    If you wanted to be perfectionist - I've realised that the issue also affects the medals list.

    The difference between gameplay and menu selection is that during gameplay, you'd expect the player character to continue to move in the direction that you hold the joystick, until you release the joystick. But during menu selection, you'd expect the cursor to move only once each time you push the joystick, regardless of how long you try to hold the joystick in that position.

    The exception to that is the medals list, which scrolls. If you move the joystick to the opposite direction too quickly whilst scrolling the menu list, it will continue to scroll in the same direction as before. But personally I don't see much point in trying to fix that. Who's going to want to switch scroll direction quickly in the medal list? I only mention it because it illustrates the nature of the issue that affects gameplay. But getting the joystick control in gameplay fixed is more important in my opinion. Thanks.

  • Palamedes

    Palamedes - 2014-02-02

    I have now tested my fix more thoroughly - and I'm afraid to say it causes problems with the library code doors. I highly suspect it will also cause problems with the puzzles - such as the armoury sliding numbers, and the dungeon jigsaw. And possibly selecting the answer in cutscene questions too, such as whether to return the statue to Olaf or not, or proceed to the Chaos and Sorceror boss fights.

    Are there any in-game variables to say whether the player is currently in a puzzle or a cutscene? I'll see if I can find those variables - and if I can, I'll try to amend the conditions in src/input.c

    The only other puzzles I can think of that might be affected are the ground floor mastermind, the left tower colour pair matcher, and the library robot instruction card programmer. If I figure out a fix, I'll make sure that it works with all of these puzzles.

  • Palamedes

    Palamedes - 2014-02-02

    I now think I've found a fix for the problem with my first fix. The file src/input.c is now as follows:

    line 540: if (input.xAxisMoved == FALSE || (game.status == IN_GAME && player.action == NULL))
    line 550: if (input.xAxisMoved == FALSE || (game.status == IN_GAME && player.action == NULL))
    line 570: if (input.yAxisMoved == FALSE || (game.status == IN_GAME && player.action == NULL))
    line 580: if (input.yAxisMoved == FALSE || (game.status == IN_GAME && player.action == NULL))

    I suspect this will work with all the puzzles and all the cutscene questions - however, so far, I have only tested it with one of the library code doors. Menu selection still works, and reversing direction quickly during normal gameplay still seems to work too. But I'll post again once I've checked more of the puzzles and cutscenes.

  • Palamedes

    Palamedes - 2014-02-08

    I've now played the whole game through, defeating both the dragon and the sorceror, and have tried two different analog joystick. There do not seem to be any further problems. Whilst defending against the dragon's fire breathing attack is obviously easier when you can turn quickly than it is when you can't, defeating the dragon is still otherwise reassuringly difficult.

    Shaking off baby slimes, blob pieces, mini gargoyles and the sorceror and dragon hold-person attacks by using the stick is doable - though I find it easier to do it by keeping one of the joystick buttons defined as a left control, and then holding the stick to the right while mashing the left button. The fact that this works is something I regard as a feature rather than a bug, but I think I should test this behaviour more thoroughly.

  • Palamedes

    Palamedes - 2014-02-08

    Have tested sorceror hold person attack more thoroughly - and it's clear that with my code fix, Edgar will change direction, no matter how quickly I move the joystick; I can't move the joystick so quickly as to make Edgar fail to respond, as is possible without this code fix. So I'm now satisfied that this fix is as good as it's ever going to be, and hope to see it implemented in the next version.



Cancel  Add attachments