diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2016-06-14 11:47:30 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2016-06-14 18:14:46 +0200 |
commit | 1d8b1da9a68a47e6b222e8d80dc8e546e52e4dcc (patch) | |
tree | 2bbcf25de732bd8a81363f452e08520087b024b5 /proto-mouse | |
parent | a8da0d997048007d3feb2e3814ba93bbfd4d4ef8 (diff) |
proto/mouse: guard against +181 -> -179 wraparound
Always use the shorter way around.
This also adds a sensitivity param.
Issue: #370
Diffstat (limited to 'proto-mouse')
-rw-r--r-- | proto-mouse/ftnoir_mousecontrols.ui | 84 | ||||
-rw-r--r-- | proto-mouse/ftnoir_protocol_mouse.cpp | 123 | ||||
-rw-r--r-- | proto-mouse/ftnoir_protocol_mouse.h | 20 | ||||
-rw-r--r-- | proto-mouse/ftnoir_protocol_mouse_dialog.cpp | 3 |
4 files changed, 184 insertions, 46 deletions
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 @@ <x>0</x> <y>0</y> <width>280</width> - <height>106</height> + <height>280</height> </rect> </property> <property name="windowTitle"> @@ -46,6 +46,25 @@ </property> </widget> </item> + <item row="1" column="0"> + <widget class="QLabel" name="textLabel2_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Map mouse Y to:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> <item row="0" column="1" colspan="2"> <widget class="QComboBox" name="cbxSelectMouse_X"> <property name="maximumSize"> @@ -148,8 +167,15 @@ </item> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="textLabel2_3"> + <item row="4" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="textLabel2_4"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -157,7 +183,7 @@ </sizepolicy> </property> <property name="text"> - <string>Map mouse Y to:</string> + <string>X axis sensitivity</string> </property> <property name="alignment"> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> @@ -168,9 +194,53 @@ </widget> </item> <item row="2" column="1"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <widget class="QSlider" name="sensitivity_x"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickInterval"> + <number>25</number> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="textLabel2_5"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Y axis sensitivity</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="wordWrap"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QSlider" name="sensitivity_y"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="tickInterval"> + <number>25</number> </property> </widget> </item> 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 <cmath> +#include <algorithm> #include <windows.h> #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<slider_value>(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<slider_value>(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<int> Mouse_X, Mouse_Y; + value<slider_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() { |