From 1d8b1da9a68a47e6b222e8d80dc8e546e52e4dcc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 14 Jun 2016 11:47:30 +0200 Subject: proto/mouse: guard against +181 -> -179 wraparound Always use the shorter way around. This also adds a sensitivity param. Issue: #370 --- proto-mouse/ftnoir_mousecontrols.ui | 84 ++++++++++++++++-- proto-mouse/ftnoir_protocol_mouse.cpp | 123 ++++++++++++++++++++------- proto-mouse/ftnoir_protocol_mouse.h | 20 +++-- proto-mouse/ftnoir_protocol_mouse_dialog.cpp | 3 + 4 files changed, 184 insertions(+), 46 deletions(-) (limited to 'proto-mouse') diff --git a/proto-mouse/ftnoir_mousecontrols.ui b/proto-mouse/ftnoir_mousecontrols.ui index b1f4bcf8..637afe2f 100644 --- a/proto-mouse/ftnoir_mousecontrols.ui +++ b/proto-mouse/ftnoir_mousecontrols.ui @@ -10,7 +10,7 @@ 0 0 280 - 106 + 280 @@ -46,6 +46,25 @@ + + + + + 0 + 0 + + + + Map mouse Y to: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + @@ -148,8 +167,15 @@ - - + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + 0 @@ -157,7 +183,7 @@ - Map mouse Y to: + X axis sensitivity Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -168,9 +194,53 @@ - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + 0 + 0 + + + + Qt::Horizontal + + + 25 + + + + + + + + 0 + 0 + + + + Y axis sensitivity + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + 25 diff --git a/proto-mouse/ftnoir_protocol_mouse.cpp b/proto-mouse/ftnoir_protocol_mouse.cpp index c0a0a868..73616785 100644 --- a/proto-mouse/ftnoir_protocol_mouse.cpp +++ b/proto-mouse/ftnoir_protocol_mouse.cpp @@ -6,48 +6,107 @@ */ #include "ftnoir_protocol_mouse.h" #include "opentrack/plugin-api.hpp" +#include +#include #include #ifndef MOUSEEVENTF_MOVE_NOCOALESCE # define MOUSEEVENTF_MOVE_NOCOALESCE 0x2000 #endif -void FTNoIR_Protocol::pose(const double *headpose ) { - RECT desktop; - const HWND hDesktop = GetDesktopWindow(); - if (hDesktop != NULL && GetWindowRect(hDesktop, &desktop)) { - // XXX TODO remove axis selector, use mapping window's - // axis selection. Mention in UI axis used. -sh 20140920 - int axis_x = s.Mouse_X; - int axis_y = s.Mouse_Y; - - int mouse_x = 0, mouse_y = 0; - - if (axis_x > 0 && axis_x <= 6) - mouse_x = headpose[axis_x-1] / (axis_x <= 3 ? 100 : 180) * 10 * desktop.right/2; - - if (axis_y > 0 && axis_y <= 6) - mouse_y = headpose[axis_y-1] / (axis_y <= 3 ? 100 : 180) * 10 * desktop.bottom/2; - - MOUSEINPUT mi; - mi.dx = mouse_x - last_x; - mi.dy = mouse_y - last_y; - mi.mouseData = 0; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; - mi.time = 0; - mi.dwExtraInfo = 0; - INPUT input; - input.type = INPUT_MOUSE; - input.mi = mi; - (void) SendInput(1, &input, sizeof(INPUT)); - - last_x = mouse_x; - last_y = mouse_y; +void FTNoIR_Protocol::pose(const double *headpose) +{ + // XXX TODO remove axis selector, use mapping window's + // axis selection. Mention in UI axis used. -sh 20140920 + const int axis_x = s.Mouse_X - 1; + const int axis_y = s.Mouse_Y - 1; + + int mouse_x = 0, mouse_y = 0; + + static constexpr double invert[] = + { + 1., 1., 1., + 1., -1., 1. + }; + + if (axis_x >= 0 && axis_x < 6) + { + mouse_x = get_value(headpose[axis_x] * invert[axis_x], + last_pos_x, + last_x, + axis_x >= 3, + static_cast(s.sensitivity_x)); + } + + if (axis_y >= 0 && axis_y < 6) + mouse_y = get_value(headpose[axis_y] * invert[axis_y], + last_pos_y, + last_y, + axis_y >= 3, + static_cast(s.sensitivity_y)); + + MOUSEINPUT mi; + mi.dx = mouse_x; + mi.dy = mouse_y; + mi.mouseData = 0; + mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; + mi.time = 0; + mi.dwExtraInfo = 0; + INPUT input; + input.type = INPUT_MOUSE; + input.mi = mi; + (void) SendInput(1, &input, sizeof(INPUT)); + + last_x = mouse_x; + last_y = mouse_y; +} + +QString FTNoIR_Protocol::game_name() +{ + return "Mouse tracker"; +} + +double FTNoIR_Protocol::get_rotation(double val, double last_pos) +{ + using std::fmod; + using std::fabs; + using std::copysign; + using std::min; + + const double x_1 = val - last_pos; + + if (x_1 > 180) + return 360 - x_1; + else if (x_1 < -180) + return 360 + x_1; + else + return x_1; +} + +int FTNoIR_Protocol::get_value(double val, double& last_pos, int& last_px, bool is_rotation, double sensitivity) +{ + static constexpr double c = 1e-1; + + if (is_rotation) + { + const double rot_delta = get_rotation(val, last_pos); + + last_pos = val; + last_px = int(rot_delta * c * sensitivity); } + else + { + val -= last_pos; + + last_pos = val; + last_px = int(val * c * sensitivity / 100 - last_px); + } + + return last_px; } bool FTNoIR_Protocol::correct() -{ +{ return true; } diff --git a/proto-mouse/ftnoir_protocol_mouse.h b/proto-mouse/ftnoir_protocol_mouse.h index f1730777..2d96915e 100644 --- a/proto-mouse/ftnoir_protocol_mouse.h +++ b/proto-mouse/ftnoir_protocol_mouse.h @@ -15,24 +15,30 @@ using namespace options; struct settings : opts { value Mouse_X, Mouse_Y; + value sensitivity_x, sensitivity_y; settings() : opts("mouse-proto"), Mouse_X(b, "mouse-x", 0), - Mouse_Y(b, "mouse-y", 0) + Mouse_Y(b, "mouse-y", 0), + sensitivity_x(b, "mouse-sensitivity-x", slider_value(200, 100, 500)), + sensitivity_y(b, "mouse-sensitivity-y", slider_value(200, 100, 500)) {} }; class FTNoIR_Protocol : public IProtocol { public: - FTNoIR_Protocol() : last_x(0), last_y(0) {} - bool correct(); - void pose( const double *headpose); - QString game_name() { - return "Mouse tracker"; - } + FTNoIR_Protocol() : last_pos_x(0), last_pos_y(0), last_x(0), last_y(0) {} + bool correct() override; + void pose( const double *headpose) override; + QString game_name() override; + + double last_pos_x, last_pos_y; int last_x, last_y; private: + static double get_rotation(double val, double last_val); + static int get_value(double val, double& last_pos, int& last_px, bool is_rotation, double sensitivity); + struct settings s; }; diff --git a/proto-mouse/ftnoir_protocol_mouse_dialog.cpp b/proto-mouse/ftnoir_protocol_mouse_dialog.cpp index 89851b61..d8517487 100644 --- a/proto-mouse/ftnoir_protocol_mouse_dialog.cpp +++ b/proto-mouse/ftnoir_protocol_mouse_dialog.cpp @@ -10,6 +10,9 @@ MOUSEControls::MOUSEControls() tie_setting(s.Mouse_X, ui.cbxSelectMouse_X); tie_setting(s.Mouse_Y, ui.cbxSelectMouse_Y); + + tie_setting(s.sensitivity_x, ui.sensitivity_x); + tie_setting(s.sensitivity_y, ui.sensitivity_y); } void MOUSEControls::doOK() { -- cgit v1.2.3