Skip to content

Commit 5b18e22

Browse files
committed
Fix mouselook
Likely with the change to SDL's 'captured mouse' mode, mouse movements during fullscreen became deltas *from the last movement*, not from the last sampled position or frame. In order to correctly measure the mouse movement, the deltas must be summed up and then reset when 'read' at input-processing time. Moving to summing the deltas threw many other mouse-related calibration factors out of whack, so these factors are re-determined empirically across a range of mice, from 400dpi 125hz to 30,000dpi 8khz. Reasonable defaults are chosen targeting an 'average' mouse of 1000dpi, and the mouse sensitivity precision is increased to allow finer user tuning.
1 parent 11f9322 commit 5b18e22

File tree

4 files changed

+22
-11
lines changed

4 files changed

+22
-11
lines changed

Descent3/ctlconfig.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@
303303
#define IDV_OPTIONS 18
304304

305305
// used for adjusting settings.
306-
#define CFG_AXIS_SENS_RANGE 20
306+
#define CFG_AXIS_SENS_RANGE 200
307307
const int16_t UID_JOYCFG = 0x1000;
308308

309309

ddio/lnxmouse.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ int sdlMouseMotionFilter(SDL_Event const *event) {
395395
} // if
396396
else {
397397
if (ddio_mouseGrabbed) {
398-
DDIO_mouse_state.dx = event->motion.xrel;
399-
DDIO_mouse_state.dy = event->motion.yrel;
398+
DDIO_mouse_state.dx += event->motion.xrel;
399+
DDIO_mouse_state.dy += event->motion.yrel;
400400
DDIO_mouse_state.x += DDIO_mouse_state.dx;
401401
DDIO_mouse_state.y += DDIO_mouse_state.dy;
402402
} // if

ddio/sdlcontroller.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,10 @@ bool sdlgameController::enum_controllers() {
876876
m_ControlList[num_devs].buttons = nbtns;
877877
m_ControlList[num_devs].flags = CTF_X_AXIS | CTF_Y_AXIS; // | (naxis>=3 ? CTF_Z_AXIS : 0);
878878
m_ControlList[num_devs].btnmask = btnmask;
879-
m_ControlList[num_devs].normalizer[0] = 320.0f;
880-
m_ControlList[num_devs].normalizer[1] = 240.0f;
879+
// normalizer is the "available area" in dots - this is the max we expect ANY mouse to EVER travel in 1.0s
880+
// if a mouse is faster than (normalizer / frame_time), rot speed will be CLAMPED to kMaxRevPerSec
881+
m_ControlList[num_devs].normalizer[0] = 100000.0f;
882+
m_ControlList[num_devs].normalizer[1] = 100000.0f;
881883
m_ControlList[num_devs].normalizer[2] = 100.0f;
882884
m_ControlList[num_devs].sens[0] = 1.0f;
883885
m_ControlList[num_devs].sens[1] = 1.0f;
@@ -1108,6 +1110,11 @@ float sdlgameController::get_button_value(int8_t controller, ct_format format, u
11081110
return val;
11091111
}
11101112

1113+
// rot: fraction of one full circle (1.0 == 360 degrees)
1114+
static constexpr angle rotationToFixAngle(double rot) {
1115+
return static_cast<angle>(std::numeric_limits<angle>::max() * rot);
1116+
}
1117+
11111118
// note controller is index into ControlList.
11121119
float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_format format, bool invert) {
11131120
struct sdlgameController::t_controller *ctldev;
@@ -1212,6 +1219,8 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form
12121219
return val;
12131220
}
12141221
if ((Current_pilot.mouselook_control) && (GAME_MODE == GetFunctionMode())) {
1222+
constexpr double kMaxRevPerSec = 10; // number of rotations when val == 1.0 (ie, max movement)
1223+
12151224
// Don't do mouselook controls if they aren't enabled in multiplayer
12161225
if ((Game_mode & GM_MULTI) && (!(Netgame.flags & NF_ALLOW_MLOOK)))
12171226
return val;
@@ -1236,7 +1245,7 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form
12361245
if (invert)
12371246
val = -val;
12381247

1239-
vm_AnglesToMatrix(&orient, 0.0, val * (((float)(65535.0f / 20)) * .5), 0.0);
1248+
vm_AnglesToMatrix(&orient, 0.0, rotationToFixAngle(val * kMaxRevPerSec * m_frame_time), 0.0);
12401249

12411250
Objects[Players[Player_num].objnum].orient = Objects[Players[Player_num].objnum].orient * orient;
12421251

@@ -1259,7 +1268,7 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form
12591268
if (invert)
12601269
val = -val;
12611270

1262-
vm_AnglesToMatrix(&orient, val * (((float)(65535.0f / 20)) * .5), 0.0, 0.0);
1271+
vm_AnglesToMatrix(&orient, rotationToFixAngle(val * kMaxRevPerSec * m_frame_time), 0.0, 0.0);
12631272

12641273
Objects[Players[Player_num].objnum].orient = Objects[Players[Player_num].objnum].orient * orient;
12651274

ui/UISystem.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@
174174
#include "renderer.h"
175175
#include "Macros.h"
176176

177+
constexpr float kDefaultMouseScale = 20;
178+
177179
#define UI_MOUSE_HOTX 2
178180
#define UI_MOUSE_HOTY 2
179181
constexpr int ui_FrameTimeMS = 50;
@@ -270,8 +272,8 @@ bool ui_MousePoll(bool buttons) {
270272
btn_mask = ddio_MouseGetState(&mx, &my, NULL, NULL);
271273
UI_input.last_mx = UI_input.mx;
272274
UI_input.last_my = UI_input.my;
273-
UI_input.mx = mx;
274-
UI_input.my = my;
275+
UI_input.mx = mx / kDefaultMouseScale;
276+
UI_input.my = my / kDefaultMouseScale;
275277
} else if (UI_cursor_show) {
276278
// if bX_count is 0, then repeat processing can occur, otherwise only real mouse events are processed.
277279
if (ddio_MouseGetEvent(&msebtn, &state)) {
@@ -537,15 +539,15 @@ bool ui_HideCursor() {
537539
}
538540
return true; // cursor was hidden before.
539541
}
542+
540543
// set user interface screen resolution
541544
void ui_SetScreenMode(int w, int h) {
542545
UI_screen_width = w;
543546
UI_screen_height = h;
544547
UI_aspect_x = (float)w / (float)FIXED_SCREEN_WIDTH;
545548
UI_aspect_y = (float)h / (float)FIXED_SCREEN_HEIGHT;
546549
ddio_MouseReset();
547-
// ddio_MouseSetLimits(0,0, UI_screen_width, UI_screen_height);
548-
ddio_MouseSetVCoords(UI_screen_width, UI_screen_height);
550+
ddio_MouseSetVCoords(UI_screen_width * kDefaultMouseScale, UI_screen_height * kDefaultMouseScale);
549551
UI_input.cur_time = timer_GetTime();
550552
// reposition all active open windows to their correct locations in this new resolution
551553
//@@ tUIWindowNode *wndnode = UIWindowList;

0 commit comments

Comments
 (0)