beyond-all-reason / spring

A powerful free cross-platform RTS game engine
https://beyond-all-reason.github.io/spring/
Other
219 stars 101 forks source link

[Feature] Lock/Unlock Mouse Position #654

Open Krogoth100 opened 1 year ago

Krogoth100 commented 1 year ago

Afaik, currently we have no feature that allows locking/unlocking mouse position for things like free camera rotation and gui control objects like boundless sliders. The variety of such operations and needs for controls are so that it's the best to have a dedicated function to control that behaviour, not tied to Spring's hotkey system. I assume, this would approve existing COFC code as well, that uses a workaround which I tested to be imperfect in terms of accuracy for a case of low FPS (a workaround including WarpMouse to make the cursor stay still, apparently is the reason of a non-negligible inaccuracy in my tests). The proposition is to add 2 functions:

All in all, this would save from quite cumbersome code with the mouse warps forth and back, as well as give an accurate behaviour.

P.S. Potentially I may come up with a PR myself in a few months (no good window to take on engine work for now).

lhog commented 1 year ago

Please explain in greater details how the behavior of locked and unlocked mouse position should be different. In layman's terms preferably.

Krogoth100 commented 1 year ago

Locked Mouse Position: Cursor freezes wherever it is, mouse coordinates (GetMouseState()) don't change. Mouse movement (delta that would be applied if mouse wasn't locked) can be retrieved via GetLastUpdateMouseMovement(). Unlocked Mouse Position: Normal, free mouse movement within screen borders. I think, GetLastUpdateMouseMovement() still should return correct delta values for convenience.

badosu commented 1 year ago

You can piggyback on MouseHandler.locked and provide UnsyncedCtrl and UnsyncedRead functions to control it.

Additionally you might have to either find an harmonious interaction with middle mouse button lock behavior or use an option for however it should differ from it.

A few fixes might be required: https://github.com/beyond-all-reason/spring/blob/4c15a8c87a2634dc06820420aefd63456f071fb4/rts/Game/UI/MouseHandler.cpp#L239-L240

sprunk commented 1 year ago

Isn't the existing Spring.WarpMouse(x, y) enough?

Krogoth100 commented 1 year ago

Isn't the existing Spring.WarpMouse(x, y) enough?

  • in some event, save current mouse x and y.
  • in widget:Update, read new x and y. Calculate dx and dy and warp to the saved position.

No, the result appears to be unsatisfactory due to jittering. Anyway, proposed feature is rather a basic feature that somehow just didn't make it (we have more advanced features in place, but not this basic one).

sprunk commented 6 months ago

SDL seems to expose SDL_SetRelativeMouseMode(SDL_TRUE/FALSE) for this.