mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-12-19 17:37:42 -05:00
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.
This commit is contained in:
@@ -303,7 +303,7 @@
|
||||
#define IDV_OPTIONS 18
|
||||
|
||||
// used for adjusting settings.
|
||||
#define CFG_AXIS_SENS_RANGE 20
|
||||
#define CFG_AXIS_SENS_RANGE 200
|
||||
const int16_t UID_JOYCFG = 0x1000;
|
||||
|
||||
|
||||
|
||||
@@ -395,8 +395,8 @@ int sdlMouseMotionFilter(SDL_Event const *event) {
|
||||
} // if
|
||||
else {
|
||||
if (ddio_mouseGrabbed) {
|
||||
DDIO_mouse_state.dx = event->motion.xrel;
|
||||
DDIO_mouse_state.dy = event->motion.yrel;
|
||||
DDIO_mouse_state.dx += event->motion.xrel;
|
||||
DDIO_mouse_state.dy += event->motion.yrel;
|
||||
DDIO_mouse_state.x += DDIO_mouse_state.dx;
|
||||
DDIO_mouse_state.y += DDIO_mouse_state.dy;
|
||||
} // if
|
||||
|
||||
@@ -876,8 +876,10 @@ bool sdlgameController::enum_controllers() {
|
||||
m_ControlList[num_devs].buttons = nbtns;
|
||||
m_ControlList[num_devs].flags = CTF_X_AXIS | CTF_Y_AXIS; // | (naxis>=3 ? CTF_Z_AXIS : 0);
|
||||
m_ControlList[num_devs].btnmask = btnmask;
|
||||
m_ControlList[num_devs].normalizer[0] = 320.0f;
|
||||
m_ControlList[num_devs].normalizer[1] = 240.0f;
|
||||
// normalizer is the "available area" in dots - this is the max we expect ANY mouse to EVER travel in 1.0s
|
||||
// if a mouse is faster than (normalizer / frame_time), rot speed will be CLAMPED to kMaxRevPerSec
|
||||
m_ControlList[num_devs].normalizer[0] = 100000.0f;
|
||||
m_ControlList[num_devs].normalizer[1] = 100000.0f;
|
||||
m_ControlList[num_devs].normalizer[2] = 100.0f;
|
||||
m_ControlList[num_devs].sens[0] = 1.0f;
|
||||
m_ControlList[num_devs].sens[1] = 1.0f;
|
||||
@@ -1108,6 +1110,11 @@ float sdlgameController::get_button_value(int8_t controller, ct_format format, u
|
||||
return val;
|
||||
}
|
||||
|
||||
// rot: fraction of one full circle (1.0 == 360 degrees)
|
||||
static constexpr angle rotationToFixAngle(double rot) {
|
||||
return static_cast<angle>(std::numeric_limits<angle>::max() * rot);
|
||||
}
|
||||
|
||||
// note controller is index into ControlList.
|
||||
float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_format format, bool invert) {
|
||||
struct sdlgameController::t_controller *ctldev;
|
||||
@@ -1212,6 +1219,8 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form
|
||||
return val;
|
||||
}
|
||||
if ((Current_pilot.mouselook_control) && (GAME_MODE == GetFunctionMode())) {
|
||||
constexpr double kMaxRevPerSec = 10; // number of rotations when val == 1.0 (ie, max movement)
|
||||
|
||||
// Don't do mouselook controls if they aren't enabled in multiplayer
|
||||
if ((Game_mode & GM_MULTI) && (!(Netgame.flags & NF_ALLOW_MLOOK)))
|
||||
return val;
|
||||
@@ -1236,7 +1245,7 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form
|
||||
if (invert)
|
||||
val = -val;
|
||||
|
||||
vm_AnglesToMatrix(&orient, 0.0, val * (((float)(65535.0f / 20)) * .5), 0.0);
|
||||
vm_AnglesToMatrix(&orient, 0.0, rotationToFixAngle(val * kMaxRevPerSec * m_frame_time), 0.0);
|
||||
|
||||
Objects[Players[Player_num].objnum].orient = Objects[Players[Player_num].objnum].orient * orient;
|
||||
|
||||
@@ -1259,7 +1268,7 @@ float sdlgameController::get_axis_value(int8_t controller, uint8_t axis, ct_form
|
||||
if (invert)
|
||||
val = -val;
|
||||
|
||||
vm_AnglesToMatrix(&orient, val * (((float)(65535.0f / 20)) * .5), 0.0, 0.0);
|
||||
vm_AnglesToMatrix(&orient, rotationToFixAngle(val * kMaxRevPerSec * m_frame_time), 0.0, 0.0);
|
||||
|
||||
Objects[Players[Player_num].objnum].orient = Objects[Players[Player_num].objnum].orient * orient;
|
||||
|
||||
|
||||
@@ -174,6 +174,8 @@
|
||||
#include "renderer.h"
|
||||
#include "Macros.h"
|
||||
|
||||
constexpr float kDefaultMouseScale = 20;
|
||||
|
||||
#define UI_MOUSE_HOTX 2
|
||||
#define UI_MOUSE_HOTY 2
|
||||
constexpr int ui_FrameTimeMS = 50;
|
||||
@@ -270,8 +272,8 @@ bool ui_MousePoll(bool buttons) {
|
||||
btn_mask = ddio_MouseGetState(&mx, &my, NULL, NULL);
|
||||
UI_input.last_mx = UI_input.mx;
|
||||
UI_input.last_my = UI_input.my;
|
||||
UI_input.mx = mx;
|
||||
UI_input.my = my;
|
||||
UI_input.mx = mx / kDefaultMouseScale;
|
||||
UI_input.my = my / kDefaultMouseScale;
|
||||
} else if (UI_cursor_show) {
|
||||
// if bX_count is 0, then repeat processing can occur, otherwise only real mouse events are processed.
|
||||
if (ddio_MouseGetEvent(&msebtn, &state)) {
|
||||
@@ -537,6 +539,7 @@ bool ui_HideCursor() {
|
||||
}
|
||||
return true; // cursor was hidden before.
|
||||
}
|
||||
|
||||
// set user interface screen resolution
|
||||
void ui_SetScreenMode(int w, int h) {
|
||||
UI_screen_width = w;
|
||||
@@ -544,8 +547,7 @@ void ui_SetScreenMode(int w, int h) {
|
||||
UI_aspect_x = (float)w / (float)FIXED_SCREEN_WIDTH;
|
||||
UI_aspect_y = (float)h / (float)FIXED_SCREEN_HEIGHT;
|
||||
ddio_MouseReset();
|
||||
// ddio_MouseSetLimits(0,0, UI_screen_width, UI_screen_height);
|
||||
ddio_MouseSetVCoords(UI_screen_width, UI_screen_height);
|
||||
ddio_MouseSetVCoords(UI_screen_width * kDefaultMouseScale, UI_screen_height * kDefaultMouseScale);
|
||||
UI_input.cur_time = timer_GetTime();
|
||||
// reposition all active open windows to their correct locations in this new resolution
|
||||
//@@ tUIWindowNode *wndnode = UIWindowList;
|
||||
|
||||
Reference in New Issue
Block a user